木邻有你前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
4.9 KiB

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
  1. <template>
  2. <view class="volunteer-ranking">
  3. <view class="ranking-header">
  4. <image class="ranking-title-img" src="/static/积分排行榜.png" mode="aspectFit"></image>
  5. <view class="more" @click="goToRankingList">
  6. <text class="more-text">更多</text>
  7. <uv-icon name="arrow-right" color="#999" size="12"></uv-icon>
  8. </view>
  9. </view>
  10. <view class="ranking-scroll-container">
  11. <scroll-view class="ranking-list" scroll-x show-scrollbar="false" enhanced="true" enable-flex="true" scroll-with-animation="true" @scroll="onScrollChange">
  12. <view class="ranking-content">
  13. <view class="ranking-item" v-for="(item, index) in rankingList" :key="index" @click="viewVolunteerDetail">
  14. <view class="avatar-container">
  15. <view class="avatar-with-border">
  16. <image :src="item.headImage || '/static/默认头像.png'" class="avatar-image" mode="aspectFill"></image>
  17. </view>
  18. </view>
  19. <view class="points-container">
  20. <image class="points-icon" src="/static/积分图标.png" mode="aspectFit"></image>
  21. <text class="volunteer-points">{{item.score}}</text>
  22. </view>
  23. <text class="volunteer-name">{{item.nickName}}</text>
  24. </view>
  25. </view>
  26. </scroll-view>
  27. </view>
  28. </view>
  29. </template>
  30. <script>
  31. export default {
  32. name: 'VolunteerRanking',
  33. data() {
  34. return {
  35. rankingList: [
  36. ],
  37. currentScrollIndex: 0
  38. }
  39. },
  40. methods: {
  41. goToRankingList() {
  42. // 跳转到排行榜详情页
  43. uni.navigateTo({
  44. url: '/subPages/index/ranking'
  45. })
  46. },
  47. viewVolunteerDetail() {
  48. uni.navigateTo({
  49. url: '/subPages/index/ranking'
  50. })
  51. },
  52. onScrollChange(e) {
  53. // 根据滚动位置更新指示器
  54. const scrollLeft = e.detail.scrollLeft;
  55. const scrollWidth = e.detail.scrollWidth;
  56. const clientWidth = e.detail.scrollWidth / this.rankingList.length * 3;
  57. // 计算当前滚动索引(每3个为一组)
  58. if (scrollLeft < clientWidth / 3) {
  59. this.currentScrollIndex = 0;
  60. } else if (scrollLeft < clientWidth * 2 / 3) {
  61. this.currentScrollIndex = 1;
  62. } else {
  63. this.currentScrollIndex = 2;
  64. }
  65. },
  66. // 获取志愿者积分排名
  67. async getVolunteerRanking() {
  68. const res = await this.$api.score.queryScoreRank({
  69. pageNo: 1,
  70. pageSize: 10
  71. })
  72. if (res.code === 200) {
  73. this.rankingList = res.result.scoreList.records
  74. }
  75. }
  76. },
  77. // async mounted() {
  78. // await this.getVolunteerRanking()
  79. // }
  80. }
  81. </script>
  82. <style lang="scss" scoped>
  83. .volunteer-ranking {
  84. background-color: #fff;
  85. margin: 20rpx;
  86. border-radius: 10rpx;
  87. padding: 20rpx;
  88. .ranking-header {
  89. display: flex;
  90. justify-content: space-between;
  91. align-items: center;
  92. margin-bottom: 20rpx;
  93. .ranking-title-img {
  94. height: 60rpx;
  95. width: 200rpx;
  96. }
  97. .more {
  98. display: flex;
  99. align-items: center;
  100. .more-text {
  101. font-size: 24rpx;
  102. color: $uni-text-color-grey;
  103. margin-right: 4rpx;
  104. }
  105. }
  106. }
  107. .ranking-scroll-container {
  108. position: relative;
  109. width: 100%;
  110. }
  111. .ranking-list {
  112. white-space: nowrap;
  113. padding: 15rpx 0;
  114. width: 100%;
  115. overflow-x: auto;
  116. -webkit-overflow-scrolling: touch;
  117. .ranking-content {
  118. display: flex;
  119. padding: 0 20rpx;
  120. min-width: max-content;
  121. }
  122. .ranking-item {
  123. display: inline-flex;
  124. flex-direction: column;
  125. align-items: center;
  126. margin-right: 40rpx;
  127. flex-shrink: 0;
  128. min-width: 100rpx;
  129. transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  130. &:hover, &:active {
  131. transform: scale(1.08);
  132. }
  133. &:last-child {
  134. margin-right: 20rpx;
  135. }
  136. .avatar-container {
  137. position: relative;
  138. width: 110rpx;
  139. height: 110rpx;
  140. display: flex;
  141. justify-content: center;
  142. align-items: center;
  143. .avatar-with-border {
  144. width: 110rpx;
  145. height: 110rpx;
  146. border: 3rpx solid #1f8bdc;
  147. border-radius: 50%;
  148. // box-shadow: 0 4rpx 12rpx rgba(33, 140, 221, 0.2);
  149. transition: all 0.3s ease;
  150. overflow: hidden;
  151. display: flex;
  152. align-items: center;
  153. justify-content: center;
  154. .avatar-image {
  155. width: 100%;
  156. height: 100%;
  157. border-radius: 50%;
  158. }
  159. }
  160. }
  161. .points-container {
  162. display: flex;
  163. align-items: center;
  164. justify-content: center;
  165. margin-top: -10rpx;
  166. background-color: #1f8bdc;
  167. border-radius: 7rpx;
  168. // padding: 4rpx 12rpx;
  169. width: 80rpx;
  170. height: 25rpx;
  171. // box-shadow: 0 2rpx 8rpx rgba(33, 140, 221, 0.3);
  172. z-index: 2;
  173. .points-icon {
  174. width: 20rpx;
  175. height: 20rpx;
  176. margin-right: 4rpx;
  177. filter: brightness(0) invert(1);
  178. }
  179. .volunteer-points {
  180. font-size: 18rpx;
  181. color: #fff;
  182. // font-weight: bold;
  183. margin: 0;
  184. }
  185. }
  186. .volunteer-name {
  187. font-size: 24rpx;
  188. color: $uni-text-color;
  189. margin-top: 10rpx;
  190. max-width: 100rpx;
  191. white-space: nowrap;
  192. overflow: hidden;
  193. text-overflow: ellipsis;
  194. font-weight: 500;
  195. }
  196. }
  197. }
  198. }
  199. </style>