木邻有你前端代码仓库
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.

220 lines
4.8 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month 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" 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: 5
  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: 100rpx;
  139. height: 100rpx;
  140. display: flex;
  141. justify-content: center;
  142. align-items: center;
  143. .avatar-with-border {
  144. width: 100rpx;
  145. height: 100rpx;
  146. border: 4rpx solid #218CDD;
  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: 8rpx;
  166. background-color: #218CDD;
  167. border-radius: 20rpx;
  168. padding: 4rpx 12rpx;
  169. box-shadow: 0 2rpx 8rpx rgba(33, 140, 221, 0.3);
  170. .points-icon {
  171. width: 20rpx;
  172. height: 20rpx;
  173. margin-right: 4rpx;
  174. filter: brightness(0) invert(1);
  175. }
  176. .volunteer-points {
  177. font-size: 20rpx;
  178. color: #fff;
  179. font-weight: bold;
  180. margin: 0;
  181. }
  182. }
  183. .volunteer-name {
  184. font-size: 24rpx;
  185. color: $uni-text-color;
  186. margin-top: 10rpx;
  187. max-width: 100rpx;
  188. white-space: nowrap;
  189. overflow: hidden;
  190. text-overflow: ellipsis;
  191. font-weight: 500;
  192. }
  193. }
  194. }
  195. }
  196. </style>