feat(家庭排行): 添加已加入家庭数量显示组件并优化布局
在排行榜卡片和家庭排行页面添加已加入家庭数量显示组件,使用NumberRoll实现数字滚动效果 优化页面布局间距,将"参与"文案统一改为"已加入"
Showing
2 changed files
with
62 additions
and
6 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-01-09 00:00:00 | 2 | * @Date: 2025-01-09 00:00:00 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-10-25 18:39:43 | 4 | + * @LastEditTime: 2025-10-25 18:48:25 |
| 5 | * @FilePath: /lls_program/src/components/RankingCard.vue | 5 | * @FilePath: /lls_program/src/components/RankingCard.vue |
| 6 | * @Description: 排行榜卡片组件 | 6 | * @Description: 排行榜卡片组件 |
| 7 | --> | 7 | --> |
| ... | @@ -48,7 +48,7 @@ | ... | @@ -48,7 +48,7 @@ |
| 48 | 48 | ||
| 49 | <view class="relative mb-2 text-white"> | 49 | <view class="relative mb-2 text-white"> |
| 50 | <view class="flex items-center justify-center"> | 50 | <view class="flex items-center justify-center"> |
| 51 | - <text class="mr-2" style="font-size: 28rpx;">参与 </text> | 51 | + <text class="mr-2" style="font-size: 28rpx;">已加入</text> |
| 52 | <NumberRoll | 52 | <NumberRoll |
| 53 | ref="numberRollRef" | 53 | ref="numberRollRef" |
| 54 | :target-value="currentTotalFamilySum" | 54 | :target-value="currentTotalFamilySum" |
| ... | @@ -301,8 +301,7 @@ const loadLeaderboardData = async (isInitialLoad = false) => { | ... | @@ -301,8 +301,7 @@ const loadLeaderboardData = async (isInitialLoad = false) => { |
| 301 | // 设置当前日期 | 301 | // 设置当前日期 |
| 302 | currentDate.value = response.data.yesterday | 302 | currentDate.value = response.data.yesterday |
| 303 | // TODO: 设置总家庭数 | 303 | // TODO: 设置总家庭数 |
| 304 | - const newTotalFamilySum = 2318; | 304 | + currentTotalFamilySum.value = 2318; |
| 305 | - currentTotalFamilySum.value = newTotalFamilySum; | ||
| 306 | } | 305 | } |
| 307 | } catch (error) { | 306 | } catch (error) { |
| 308 | console.error('获取排行榜数据失败:', error) | 307 | console.error('获取排行榜数据失败:', error) | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-09-01 13:07:52 | 2 | * @Date: 2025-09-01 13:07:52 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-10-22 16:21:59 | 4 | + * @LastEditTime: 2025-10-25 18:52:07 |
| 5 | * @FilePath: /lls_program/src/pages/FamilyRank/index.vue | 5 | * @FilePath: /lls_program/src/pages/FamilyRank/index.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -44,6 +44,21 @@ | ... | @@ -44,6 +44,21 @@ |
| 44 | <view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: 70rpx; font-size: 23rpx;" @tap="joinOrganization">助力码</view> | 44 | <view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: 70rpx; font-size: 23rpx;" @tap="joinOrganization">助力码</view> |
| 45 | </view> | 45 | </view> |
| 46 | 46 | ||
| 47 | + <!-- 参与家庭数量显示 --> | ||
| 48 | + <view v-if="!loading" class="family-count-display"> | ||
| 49 | + <view class="flex items-center justify-center text-white mb-4"> | ||
| 50 | + <text class="mr-2" style="font-size: 28rpx;">已加入</text> | ||
| 51 | + <NumberRoll | ||
| 52 | + ref="numberRollRef" | ||
| 53 | + :target-value="currentTotalFamilySum" | ||
| 54 | + :digit-count="currentTotalFamilySum.length" | ||
| 55 | + :duration="1500" | ||
| 56 | + :digit-delay="150" | ||
| 57 | + /> | ||
| 58 | + <text class="ml-2" style="font-size: 28rpx;">个家庭</text> | ||
| 59 | + </view> | ||
| 60 | + </view> | ||
| 61 | + | ||
| 47 | <!-- 助力榜空状态提示 --> | 62 | <!-- 助力榜空状态提示 --> |
| 48 | <view v-if="!loading && activeTab === 'support' && (!supportData || !supportData.families || supportData.families.length === 0)" class="support-empty-state"> | 63 | <view v-if="!loading && activeTab === 'support' && (!supportData || !supportData.families || supportData.families.length === 0)" class="support-empty-state"> |
| 49 | <view class="empty-image"> | 64 | <view class="empty-image"> |
| ... | @@ -191,6 +206,7 @@ import { ref, computed, onMounted } from 'vue' | ... | @@ -191,6 +206,7 @@ import { ref, computed, onMounted } from 'vue' |
| 191 | import Taro from '@tarojs/taro' | 206 | import Taro from '@tarojs/taro' |
| 192 | import { IconFont } from '@nutui/icons-vue-taro'; | 207 | import { IconFont } from '@nutui/icons-vue-taro'; |
| 193 | import BackToTop from '@/components/BackToTop.vue' | 208 | import BackToTop from '@/components/BackToTop.vue' |
| 209 | +import NumberRoll from '@/components/NumberRoll.vue' | ||
| 194 | // 默认头像 | 210 | // 默认头像 |
| 195 | const defaultAvatar = 'https://cdn.ipadbiz.cn/lls_prog/images/%E5%85%A8%E5%AE%B6%E7%A6%8F3_%E5%89%AF%E6%9C%AC.jpg?imageMogr2/strip/quality/60' | 211 | const defaultAvatar = 'https://cdn.ipadbiz.cn/lls_prog/images/%E5%85%A8%E5%AE%B6%E7%A6%8F3_%E5%89%AF%E6%9C%AC.jpg?imageMogr2/strip/quality/60' |
| 196 | const supportImg = 'https://cdn.ipadbiz.cn/lls_prog/images/support_img_1.png' | 212 | const supportImg = 'https://cdn.ipadbiz.cn/lls_prog/images/support_img_1.png' |
| ... | @@ -209,6 +225,12 @@ const shanghaiRegionOptions = computed(() => { | ... | @@ -209,6 +225,12 @@ const shanghaiRegionOptions = computed(() => { |
| 209 | })) | 225 | })) |
| 210 | }) | 226 | }) |
| 211 | 227 | ||
| 228 | +// NumberRoll组件引用 | ||
| 229 | +const numberRollRef = ref(null) | ||
| 230 | + | ||
| 231 | +// 是否已触发数字滚动 | ||
| 232 | +const hasTriggeredNumberRoll = ref(false) | ||
| 233 | + | ||
| 212 | // 当前激活的tab | 234 | // 当前激活的tab |
| 213 | const activeTab = ref('') | 235 | const activeTab = ref('') |
| 214 | 236 | ||
| ... | @@ -242,12 +264,32 @@ const handleRankAskClick = () => { | ... | @@ -242,12 +264,32 @@ const handleRankAskClick = () => { |
| 242 | } | 264 | } |
| 243 | 265 | ||
| 244 | /** | 266 | /** |
| 267 | + * 触发数字滚动动画 | ||
| 268 | + */ | ||
| 269 | +const triggerNumberRoll = () => { | ||
| 270 | + if (numberRollRef.value && !hasTriggeredNumberRoll.value) { | ||
| 271 | + numberRollRef.value.start() | ||
| 272 | + hasTriggeredNumberRoll.value = true | ||
| 273 | + } | ||
| 274 | +} | ||
| 275 | + | ||
| 276 | +/** | ||
| 277 | + * 重置数字滚动状态 | ||
| 278 | + */ | ||
| 279 | +const resetNumberRoll = () => { | ||
| 280 | + hasTriggeredNumberRoll.value = false | ||
| 281 | +} | ||
| 282 | + | ||
| 283 | +/** | ||
| 245 | * 切换tab | 284 | * 切换tab |
| 246 | * @param {string} tab - tab名称 | 285 | * @param {string} tab - tab名称 |
| 247 | */ | 286 | */ |
| 248 | const switchTab = async (tab) => { | 287 | const switchTab = async (tab) => { |
| 249 | if (activeTab.value === tab) return | 288 | if (activeTab.value === tab) return |
| 250 | 289 | ||
| 290 | + // 重置数字滚动状态 | ||
| 291 | + resetNumberRoll() | ||
| 292 | + | ||
| 251 | // 开始切换动画 | 293 | // 开始切换动画 |
| 252 | isContentSwitching.value = true | 294 | isContentSwitching.value = true |
| 253 | 295 | ||
| ... | @@ -261,6 +303,11 @@ const switchTab = async (tab) => { | ... | @@ -261,6 +303,11 @@ const switchTab = async (tab) => { |
| 261 | // 内容切换后,结束切换状态,开始淡入动画 | 303 | // 内容切换后,结束切换状态,开始淡入动画 |
| 262 | setTimeout(() => { | 304 | setTimeout(() => { |
| 263 | isContentSwitching.value = false | 305 | isContentSwitching.value = false |
| 306 | + | ||
| 307 | + // 延迟1秒触发数字滚动动画 | ||
| 308 | + setTimeout(() => { | ||
| 309 | + triggerNumberRoll() | ||
| 310 | + }, 1000) | ||
| 264 | }, 50) | 311 | }, 50) |
| 265 | }, 200) | 312 | }, 200) |
| 266 | } | 313 | } |
| ... | @@ -323,6 +370,8 @@ const loadLeaderboardData = async (isInitialLoad = false) => { | ... | @@ -323,6 +370,8 @@ const loadLeaderboardData = async (isInitialLoad = false) => { |
| 323 | leaderboardData.value = response.data | 370 | leaderboardData.value = response.data |
| 324 | } | 371 | } |
| 325 | currentDate.value = response.data.yesterday | 372 | currentDate.value = response.data.yesterday |
| 373 | + // TODO: 设置总家庭数 | ||
| 374 | + currentTotalFamilySum.value = 2318; | ||
| 326 | } | 375 | } |
| 327 | } catch (error) { | 376 | } catch (error) { |
| 328 | console.error('获取排行榜数据失败:', error) | 377 | console.error('获取排行榜数据失败:', error) |
| ... | @@ -382,6 +431,9 @@ const getTabDisplayName = (region) => { | ... | @@ -382,6 +431,9 @@ const getTabDisplayName = (region) => { |
| 382 | } | 431 | } |
| 383 | } | 432 | } |
| 384 | 433 | ||
| 434 | +// 当前总家庭数 | ||
| 435 | +const currentTotalFamilySum = ref(0); | ||
| 436 | + | ||
| 385 | /** | 437 | /** |
| 386 | * 计算前三名数据 | 438 | * 计算前三名数据 |
| 387 | */ | 439 | */ |
| ... | @@ -472,6 +524,11 @@ onMounted(async () => { | ... | @@ -472,6 +524,11 @@ onMounted(async () => { |
| 472 | activeTab.value = 'shanghai' | 524 | activeTab.value = 'shanghai' |
| 473 | // 加载排行榜数据 | 525 | // 加载排行榜数据 |
| 474 | await loadLeaderboardData(true) | 526 | await loadLeaderboardData(true) |
| 527 | + | ||
| 528 | + // 延迟1秒触发数字滚动动画 | ||
| 529 | + setTimeout(() => { | ||
| 530 | + triggerNumberRoll() | ||
| 531 | + }, 1000) | ||
| 475 | }) | 532 | }) |
| 476 | </script> | 533 | </script> |
| 477 | 534 | ||
| ... | @@ -561,7 +618,7 @@ onMounted(async () => { | ... | @@ -561,7 +618,7 @@ onMounted(async () => { |
| 561 | color: rgba(255, 255, 255, 0.8); | 618 | color: rgba(255, 255, 255, 0.8); |
| 562 | text-align: center; | 619 | text-align: center; |
| 563 | margin-top: 40rpx; | 620 | margin-top: 40rpx; |
| 564 | - margin-bottom: 40rpx; | 621 | + margin-bottom: 10rpx; |
| 565 | } | 622 | } |
| 566 | } | 623 | } |
| 567 | 624 | ... | ... |
-
Please register or login to post a comment