hookehuyr

feat(排行榜): 添加助力榜功能并替换点击事件为tap

实现助力榜功能,包括mock数据、显示逻辑和格式化方法
将click事件统一替换为tap事件以兼容移动端
......@@ -8,10 +8,10 @@
<view class="overlay-body">
<view class="overlay-content">
<!-- 广告图片容器 - 支持滚动 -->
<scroll-view
class="ad-scroll-container"
<scroll-view
class="ad-scroll-container"
scroll-y
@click="handleAdClick"
@tap="handleAdClick"
>
<image
:src="adConfig.adImageUrl"
......@@ -22,7 +22,7 @@
</scroll-view>
<!-- 关闭按钮 -->
<view class="close-button" @click="handleClose">
<view class="close-button" @tap="handleClose">
<Close size="24" class="close-icon" />
</view>
</view>
......
<!--
* @Date: 2025-01-09 00:00:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-16 11:22:44
* @LastEditTime: 2025-09-18 16:45:21
* @FilePath: /lls_program/src/components/RankingCard.vue
* @Description: 排行榜卡片组件
-->
......@@ -52,13 +52,13 @@
<image src="https://cdn.ipadbiz.cn/lls_prog/images/crow-silver.png" class="w-5 h-5" mode="aspectFill" />
</view>
<view class="avatar">
<image :src="topRanks[1]?.avatar_url || defaultAvatar" class="avatar-img" mode="aspectFill" />
<image :src="activeTab === 'support' ? (topRanks[1]?.logo || defaultAvatar) : (topRanks[1]?.avatar_url || defaultAvatar)" class="avatar-img" mode="aspectFill" />
</view>
<view class="family-name">{{ topRanks[1]?.name }}</view>
<view class="leader-name">大家长:{{ topRanks[1]?.created_by_nickname }}</view>
<view class="family-name">{{ activeTab === 'support' ? topRanks[1]?.name : topRanks[1]?.name }}</view>
<view class="leader-name">{{ activeTab === 'support' ? `${topRanks[1]?.family_count}个家庭` : `大家长:${topRanks[1]?.created_by_nickname}` }}</view>
<view class="rank-number">
<view class="rank-num">2</view>
<view class="steps-in-rank">{{ formatSteps(topRanks[1]?.step) }}</view>
<view class="steps-in-rank">{{ activeTab === 'support' ? formatSupportSteps(topRanks[1]?.total_steps) : formatSteps(topRanks[1]?.step) }}</view>
</view>
</view>
......@@ -68,13 +68,13 @@
<image src="https://cdn.ipadbiz.cn/lls_prog/images/crow-gold.png" class="w-5 h-5" mode="aspectFill" />
</view>
<view class="avatar">
<image :src="topRanks[0]?.avatar_url || defaultAvatar" class="avatar-img" mode="aspectFill" />
<image :src="activeTab === 'support' ? (topRanks[0]?.logo || defaultAvatar) : (topRanks[0]?.avatar_url || defaultAvatar)" class="avatar-img" mode="aspectFill" />
</view>
<view class="family-name">{{ topRanks[0]?.name }}</view>
<view class="leader-name">大家长:{{ topRanks[0]?.created_by_nickname }}</view>
<view class="leader-name">{{ activeTab === 'support' ? `${topRanks[0]?.family_count}个家庭` : `大家长:${topRanks[0]?.created_by_nickname}` }}</view>
<view class="rank-number">
<view class="rank-num">1</view>
<view class="steps-in-rank">{{ formatSteps(topRanks[0]?.step) }}</view>
<view class="steps-in-rank">{{ activeTab === 'support' ? formatSupportSteps(topRanks[0]?.total_steps) : formatSteps(topRanks[0]?.step) }}</view>
</view>
</view>
......@@ -84,13 +84,13 @@
<image src="https://cdn.ipadbiz.cn/lls_prog/images/crow-bronze.png" class="w-5 h-5" mode="aspectFill" />
</view>
<view class="avatar">
<image :src="topRanks[2]?.avatar_url || defaultAvatar" class="avatar-img" mode="aspectFill" />
<image :src="activeTab === 'support' ? (topRanks[2]?.logo || defaultAvatar) : (topRanks[2]?.avatar_url || defaultAvatar)" class="avatar-img" mode="aspectFill" />
</view>
<view class="family-name">{{ topRanks[2]?.name }}</view>
<view class="leader-name">大家长:{{ topRanks[2]?.created_by_nickname }}</view>
<view class="leader-name">{{ activeTab === 'support' ? `${topRanks[2]?.family_count}个家庭` : `大家长:${topRanks[2]?.created_by_nickname}` }}</view>
<view class="rank-number">
<view class="rank-num">3</view>
<view class="steps-in-rank">{{ formatSteps(topRanks[2]?.step) }}</view>
<view class="steps-in-rank">{{ activeTab === 'support' ? formatSupportSteps(topRanks[2]?.total_steps) : formatSteps(topRanks[2]?.step) }}</view>
</view>
</view>
</view>
......@@ -112,7 +112,7 @@
</view>
</view>
<view class="my-rank-right">
<view class="my-steps">{{ formatStepsForList(myRank.step) }}</view>
<view class="my-steps">{{ activeTab === 'support' ? formatSupportSteps(myRank.step) : formatStepsForList(myRank.step) }}</view>
<view class="rank-status">{{ myRank.status }}</view>
</view>
</view>
......@@ -155,6 +155,63 @@ const isContentSwitching = ref(false)
// 排行榜数据
const leaderboardData = ref(null)
// 助力榜mock数据
const supportData = ref({
yesterday: '2024年1月15日',
kindergartens: [
{
id: 1,
name: '阳光幼儿园',
logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg',
family_count: 156,
total_steps: 430000
},
{
id: 2,
name: '彩虹幼儿园',
logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg',
family_count: 142,
total_steps: 380000
},
{
id: 3,
name: '小星星幼儿园',
logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg',
family_count: 128,
total_steps: 320000
},
{
id: 4,
name: '快乐幼儿园',
logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg',
family_count: 115,
total_steps: 280000
},
{
id: 5,
name: '智慧幼儿园',
logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg',
family_count: 98,
total_steps: 250000
},
{
id: 6,
name: '梦想幼儿园',
logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg',
family_count: 87,
total_steps: 220000
}
],
current_kindergarten: {
id: 7,
name: '我的幼儿园',
logo: 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg',
family_count: 45,
total_steps: 120000,
rank: 8
}
})
// 加载状态
const loading = ref(false)
......@@ -168,10 +225,22 @@ const currentDate = ref('')
const switchTab = async (tab) => {
if (activeTab.value === tab) return
// 助力榜暂时没有数据,显示提示
// 助力榜使用mock数据
if (tab === 'support') {
// TODO: 助力榜功能待开发
console.log('助力榜功能待开发')
// 开始切换动画
isContentSwitching.value = true
// 延迟切换内容,让淡出动画先执行
setTimeout(() => {
activeTab.value = tab
// 设置助力榜的日期
currentDate.value = supportData.value.yesterday
// 内容切换后,结束切换状态,开始淡入动画
setTimeout(() => {
isContentSwitching.value = false
}, 50)
}, 200)
return
}
......@@ -288,6 +357,20 @@ const formatStepsForList = (steps) => {
}
/**
* 格式化助力榜步数显示(超过10000显示为万+格式)
* @param {number} steps - 步数
* @returns {string} 格式化后的步数
*/
const formatSupportSteps = (steps) => {
if (!steps) return '0'
if (steps >= 10000) {
const wan = Math.floor(steps / 10000)
return `${wan}万+`
}
return steps.toLocaleString()
}
/**
* 处理查看更多点击事件
*/
const handleViewMore = () => {
......@@ -300,6 +383,15 @@ const handleViewMore = () => {
// 计算前三名数据
const topRanks = computed(() => {
if (activeTab.value === 'support') {
// 助力榜数据
if (!supportData.value || !supportData.value.kindergartens) {
return []
}
return supportData.value.kindergartens.slice(0, 3)
}
// 家庭排行榜数据
if (!leaderboardData.value || !leaderboardData.value.families) {
return []
}
......@@ -308,6 +400,25 @@ const topRanks = computed(() => {
// 计算我的排名信息
const myRank = computed(() => {
if (activeTab.value === 'support') {
// 助力榜我的幼儿园信息
if (!supportData.value || !supportData.value.current_kindergarten) {
return null
}
const currentKindergarten = supportData.value.current_kindergarten
return {
...currentKindergarten,
name: currentKindergarten.name,
avatar_url: currentKindergarten.logo,
step: currentKindergarten.total_steps,
created_by_nickname: `${currentKindergarten.family_count}个家庭`,
status: currentKindergarten.rank > 100 ? '未上榜' : '已上榜',
isNotRanked: !currentKindergarten.rank || currentKindergarten.rank === 0 || currentKindergarten.rank > 100
}
}
// 家庭排行榜我的排名信息
if (!leaderboardData.value || !leaderboardData.value.current_family) {
return null
}
......
This diff is collapsed. Click to expand it.