hookehuyr

feat(弹幕组件): 添加原生弹幕组件并集成到排行榜页面

- 新增 NativeDanmuComponent 原生弹幕组件,支持多轨道弹幕展示
- 在家庭排行榜页面集成弹幕功能,展示助力榜内容
- 调整排行榜卡片布局和样式,优化助力码按钮位置
- 添加弹幕点击和悬停事件处理逻辑
......@@ -13,6 +13,7 @@ declare module 'vue' {
BottomNav: typeof import('./src/components/BottomNav.vue')['default']
FamilyAlbum: typeof import('./src/components/FamilyAlbum.vue')['default']
GlassCard: typeof import('./src/components/GlassCard.vue')['default']
NativeDanmuComponent: typeof import('./src/components/NativeDanmuComponent.vue')['default']
NavBar: typeof import('./src/components/navBar.vue')['default']
NumberRoll: typeof import('./src/components/NumberRoll.vue')['default']
NutActionSheet: typeof import('@nutui/nutui-taro')['ActionSheet']
......
This diff is collapsed. Click to expand it.
<!--
* @Date: 2025-01-09 00:00:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-10-28 13:33:56
* @LastEditTime: 2025-10-28 16:24:46
* @FilePath: /lls_program/src/components/RankingCard.vue
* @Description: 排行榜卡片组件
-->
<template>
<view class="ranking-card bg-blue-500 bg-opacity-50">
<!-- 卡片头部 -->
<view class="card-header">
<view class="card-header" style="margin: 40rpx;">
<view class="card-title flex items-center">
<IconFont size="20" name="https://cdn.ipadbiz.cn/lls_prog/icon/%E5%A5%96%E6%9D%AF.png" />
<text class="ml-2">家庭步数总榜</text>
......@@ -17,7 +17,7 @@
</view>
<!-- 顶部导航 -->
<view class="nav-tabs">
<view class="nav-tabs" style="margin: 40rpx;">
<!-- 滑动指示器 -->
<view
class="tab-indicator"
......@@ -39,12 +39,12 @@
</view>
<!-- 排行榜内容 -->
<view class="rank-content" :class="{ 'content-switching': isContentSwitching }">
<view class="rank-content" :class="{ 'content-switching': isContentSwitching }" style="margin: 40rpx;">
<!-- 排行榜日期 -->
<view class="rank-date relative">
<!-- <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text v-if="activeTab !== 'shanghai'" class="ml-2">排名</text><IconFont name="ask" size="16" class="ml-2" @click="handleRankAskClick"></IconFont></view> -->
<view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text class="ml-2">排名</text><IconFont name="ask" size="16" class="ml-2" @click="handleRankAskClick"></IconFont></view>
<view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: 0rpx; top: 50rpx; font-size: 23rpx; z-index: 999;" @tap="joinOrganization">助力码</view>
<view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: -30rpx; top: -5rpx; font-size: 23rpx; z-index: 999;" @tap="joinOrganization">助力码</view>
</view>
<!-- <view v-if="activeTab === 'shanghai'" class="relative mb-2 text-white">
......@@ -124,9 +124,21 @@
</view>
</view>
<!-- 弹幕显示助力榜内容 -->
<view v-if="activeTab === 'support'" class="danmu-section">
<NativeDanmuComponent
:container-height="700"
:show-controls="true"
:track-count="3"
@danmu-click="handleDanmuClick"
@danmu-hover="handleDanmuHover"
ref="danmuRef"
/>
</view>
<!-- 我的排名卡片 -->
<!-- 特殊写法 因为直接写一个排名卡片排名数字有被截断问题 -->
<view v-if="myRank && topRanks.length > 0 && activeTab !== 'support'" class="my-rank-section">
<view v-if="myRank && topRanks.length > 0 && activeTab !== 'support'" class="my-rank-section" style="margin: 40rpx;">
<view class="my-rank-content">
<view class="my-rank-left">
<view class="my-rank-number">
......@@ -145,7 +157,7 @@
</view>
</view>
</view>
<view v-if="myRank && !topRanks.length && activeTab !== 'support'" class="my-rank-section">
<view v-if="myRank && !topRanks.length && activeTab !== 'support'" class="my-rank-section" style="margin: 40rpx;">
<view class="my-rank-content">
<view class="my-rank-left">
<view class="my-rank-number">
......@@ -192,7 +204,8 @@
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import Taro from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro';
import NumberRoll from './NumberRoll.vue'
// import NumberRoll from './NumberRoll.vue'
import NativeDanmuComponent from '@/components/NativeDanmuComponent.vue'
// 默认头像
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'
// 助力榜图片
......@@ -510,6 +523,27 @@ const refreshData = async () => {
await loadLeaderboardData(true)
}
/**
* 弹幕组件相关
*/
const danmuRef = ref(null)
// 处理弹幕点击事件
const handleDanmuClick = (familyData) => {
console.log('弹幕点击:', familyData)
Taro.showToast({
title: `点击了${familyData.familyName}`,
icon: 'none',
duration: 2000
})
}
// 处理弹幕悬停事件
const handleDanmuHover = (familyData) => {
console.log('弹幕悬停:', familyData)
}
/**
* 页面初始化
*/
......@@ -539,7 +573,7 @@ defineExpose({
// background: linear-gradient(180deg, var(--primary-color) 0%, var(--primary-color) 100%);
// background: var(--primary-color);
border-radius: 20rpx;
padding: 40rpx;
// padding: 40rpx;
margin: 30rpx;
margin-bottom: 0;
position: relative;
......
<!--
* @Date: 2025-09-01 13:07:52
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-10-28 13:32:48
* @LastEditTime: 2025-10-28 16:04:30
* @FilePath: /lls_program/src/pages/FamilyRank/index.vue
* @Description: 文件描述
-->
......@@ -42,7 +42,7 @@
<view v-if="!loading" class="rank-date relative">
<!-- <view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text v-if="activeTab !== 'shanghai'" class="ml-2">排名</text><IconFont name="ask" size="14" class="ml-2" @click="handleRankAskClick"></IconFont></view> -->
<view class="flex items-center justify-center"><text class="mr-2">截止昨日</text>{{ currentDate }}<text class="ml-2">排名</text><IconFont name="ask" size="14" class="ml-2" @click="handleRankAskClick"></IconFont></view>
<view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: 40rpx; top: 50rpx; font-size: 23rpx;" @tap="joinOrganization">助力码</view>
<view v-if="activeTab === 'support'" class="absolute font-bold text-white bg-orange-500 top-0 rounded-full px-4 py-1" style="right: 45rpx; top: -5rpx; font-size: 23rpx;" @tap="joinOrganization">助力码</view>
</view>
<!-- 参与家庭数量显示 -->
......@@ -154,7 +154,18 @@
<view class="no-data-text">暂无助力排行榜更多数据</view>
</view> -->
</view>
<!-- 弹幕显示助力榜内容 -->
<view v-if="activeTab === 'support'" class="danmu-section mt-8">
<NativeDanmuComponent
:container-height="1200"
:show-controls="true"
:track-count="7"
@danmu-click="handleDanmuClick"
@danmu-hover="handleDanmuHover"
ref="danmuRef"
/>
</view>
<!-- 我的排名悬浮卡片 -->
......@@ -209,8 +220,8 @@ import { ref, computed, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro';
import BackToTop from '@/components/BackToTop.vue'
import NativeDanmuComponent from '@/components/NativeDanmuComponent.vue'
// import NumberRoll from '@/components/NumberRoll.vue'
import vueDanmaku from 'vue-danmaku'
// 默认头像
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'
const supportImg = 'https://cdn.ipadbiz.cn/lls_prog/images/support_img_1.png'
......@@ -268,6 +279,26 @@ const handleRankAskClick = () => {
}
/**
* 弹幕组件相关
*/
const danmuRef = ref(null)
// 处理弹幕点击事件
const handleDanmuClick = (familyData) => {
console.log('弹幕点击:', familyData)
Taro.showToast({
title: `点击了${familyData.familyName}`,
icon: 'none',
duration: 2000
})
}
// 处理弹幕悬停事件
const handleDanmuHover = (familyData) => {
console.log('弹幕悬停:', familyData)
}
/**
* 触发数字滚动动画
*/
const triggerNumberRoll = () => {
......@@ -1039,7 +1070,5 @@ onMounted(async () => {
}
}
}
}
</style>
......