hookehuyr

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

- 新增 NativeDanmuComponent 原生弹幕组件,支持多轨道弹幕展示
- 在家庭排行榜页面集成弹幕功能,展示助力榜内容
- 调整排行榜卡片布局和样式,优化助力码按钮位置
- 添加弹幕点击和悬停事件处理逻辑
...@@ -13,6 +13,7 @@ declare module 'vue' { ...@@ -13,6 +13,7 @@ declare module 'vue' {
13 BottomNav: typeof import('./src/components/BottomNav.vue')['default'] 13 BottomNav: typeof import('./src/components/BottomNav.vue')['default']
14 FamilyAlbum: typeof import('./src/components/FamilyAlbum.vue')['default'] 14 FamilyAlbum: typeof import('./src/components/FamilyAlbum.vue')['default']
15 GlassCard: typeof import('./src/components/GlassCard.vue')['default'] 15 GlassCard: typeof import('./src/components/GlassCard.vue')['default']
16 + NativeDanmuComponent: typeof import('./src/components/NativeDanmuComponent.vue')['default']
16 NavBar: typeof import('./src/components/navBar.vue')['default'] 17 NavBar: typeof import('./src/components/navBar.vue')['default']
17 NumberRoll: typeof import('./src/components/NumberRoll.vue')['default'] 18 NumberRoll: typeof import('./src/components/NumberRoll.vue')['default']
18 NutActionSheet: typeof import('@nutui/nutui-taro')['ActionSheet'] 19 NutActionSheet: typeof import('@nutui/nutui-taro')['ActionSheet']
......
This diff is collapsed. Click to expand it.
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-28 13:33:56 4 + * @LastEditTime: 2025-10-28 16:24:46
5 * @FilePath: /lls_program/src/components/RankingCard.vue 5 * @FilePath: /lls_program/src/components/RankingCard.vue
6 * @Description: 排行榜卡片组件 6 * @Description: 排行榜卡片组件
7 --> 7 -->
8 <template> 8 <template>
9 <view class="ranking-card bg-blue-500 bg-opacity-50"> 9 <view class="ranking-card bg-blue-500 bg-opacity-50">
10 <!-- 卡片头部 --> 10 <!-- 卡片头部 -->
11 - <view class="card-header"> 11 + <view class="card-header" style="margin: 40rpx;">
12 <view class="card-title flex items-center"> 12 <view class="card-title flex items-center">
13 <IconFont size="20" name="https://cdn.ipadbiz.cn/lls_prog/icon/%E5%A5%96%E6%9D%AF.png" /> 13 <IconFont size="20" name="https://cdn.ipadbiz.cn/lls_prog/icon/%E5%A5%96%E6%9D%AF.png" />
14 <text class="ml-2">家庭步数总榜</text> 14 <text class="ml-2">家庭步数总榜</text>
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 </view> 17 </view>
18 18
19 <!-- 顶部导航 --> 19 <!-- 顶部导航 -->
20 - <view class="nav-tabs"> 20 + <view class="nav-tabs" style="margin: 40rpx;">
21 <!-- 滑动指示器 --> 21 <!-- 滑动指示器 -->
22 <view 22 <view
23 class="tab-indicator" 23 class="tab-indicator"
...@@ -39,12 +39,12 @@ ...@@ -39,12 +39,12 @@
39 </view> 39 </view>
40 40
41 <!-- 排行榜内容 --> 41 <!-- 排行榜内容 -->
42 - <view class="rank-content" :class="{ 'content-switching': isContentSwitching }"> 42 + <view class="rank-content" :class="{ 'content-switching': isContentSwitching }" style="margin: 40rpx;">
43 <!-- 排行榜日期 --> 43 <!-- 排行榜日期 -->
44 <view class="rank-date relative"> 44 <view class="rank-date relative">
45 <!-- <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> --> 45 <!-- <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> -->
46 <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> 46 <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>
47 - <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> 47 + <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>
48 </view> 48 </view>
49 49
50 <!-- <view v-if="activeTab === 'shanghai'" class="relative mb-2 text-white"> 50 <!-- <view v-if="activeTab === 'shanghai'" class="relative mb-2 text-white">
...@@ -124,9 +124,21 @@ ...@@ -124,9 +124,21 @@
124 </view> 124 </view>
125 </view> 125 </view>
126 126
127 + <!-- 弹幕显示助力榜内容 -->
128 + <view v-if="activeTab === 'support'" class="danmu-section">
129 + <NativeDanmuComponent
130 + :container-height="700"
131 + :show-controls="true"
132 + :track-count="3"
133 + @danmu-click="handleDanmuClick"
134 + @danmu-hover="handleDanmuHover"
135 + ref="danmuRef"
136 + />
137 + </view>
138 +
127 <!-- 我的排名卡片 --> 139 <!-- 我的排名卡片 -->
128 <!-- 特殊写法 因为直接写一个排名卡片排名数字有被截断问题 --> 140 <!-- 特殊写法 因为直接写一个排名卡片排名数字有被截断问题 -->
129 - <view v-if="myRank && topRanks.length > 0 && activeTab !== 'support'" class="my-rank-section"> 141 + <view v-if="myRank && topRanks.length > 0 && activeTab !== 'support'" class="my-rank-section" style="margin: 40rpx;">
130 <view class="my-rank-content"> 142 <view class="my-rank-content">
131 <view class="my-rank-left"> 143 <view class="my-rank-left">
132 <view class="my-rank-number"> 144 <view class="my-rank-number">
...@@ -145,7 +157,7 @@ ...@@ -145,7 +157,7 @@
145 </view> 157 </view>
146 </view> 158 </view>
147 </view> 159 </view>
148 - <view v-if="myRank && !topRanks.length && activeTab !== 'support'" class="my-rank-section"> 160 + <view v-if="myRank && !topRanks.length && activeTab !== 'support'" class="my-rank-section" style="margin: 40rpx;">
149 <view class="my-rank-content"> 161 <view class="my-rank-content">
150 <view class="my-rank-left"> 162 <view class="my-rank-left">
151 <view class="my-rank-number"> 163 <view class="my-rank-number">
...@@ -192,7 +204,8 @@ ...@@ -192,7 +204,8 @@
192 import { ref, computed, onMounted, watch, nextTick } from 'vue' 204 import { ref, computed, onMounted, watch, nextTick } from 'vue'
193 import Taro from '@tarojs/taro' 205 import Taro from '@tarojs/taro'
194 import { IconFont } from '@nutui/icons-vue-taro'; 206 import { IconFont } from '@nutui/icons-vue-taro';
195 -import NumberRoll from './NumberRoll.vue' 207 +// import NumberRoll from './NumberRoll.vue'
208 +import NativeDanmuComponent from '@/components/NativeDanmuComponent.vue'
196 // 默认头像 209 // 默认头像
197 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' 210 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'
198 // 助力榜图片 211 // 助力榜图片
...@@ -510,6 +523,27 @@ const refreshData = async () => { ...@@ -510,6 +523,27 @@ const refreshData = async () => {
510 await loadLeaderboardData(true) 523 await loadLeaderboardData(true)
511 } 524 }
512 525
526 +
527 +/**
528 + * 弹幕组件相关
529 + */
530 +const danmuRef = ref(null)
531 +
532 +// 处理弹幕点击事件
533 +const handleDanmuClick = (familyData) => {
534 + console.log('弹幕点击:', familyData)
535 + Taro.showToast({
536 + title: `点击了${familyData.familyName}`,
537 + icon: 'none',
538 + duration: 2000
539 + })
540 +}
541 +
542 +// 处理弹幕悬停事件
543 +const handleDanmuHover = (familyData) => {
544 + console.log('弹幕悬停:', familyData)
545 +}
546 +
513 /** 547 /**
514 * 页面初始化 548 * 页面初始化
515 */ 549 */
...@@ -539,7 +573,7 @@ defineExpose({ ...@@ -539,7 +573,7 @@ defineExpose({
539 // background: linear-gradient(180deg, var(--primary-color) 0%, var(--primary-color) 100%); 573 // background: linear-gradient(180deg, var(--primary-color) 0%, var(--primary-color) 100%);
540 // background: var(--primary-color); 574 // background: var(--primary-color);
541 border-radius: 20rpx; 575 border-radius: 20rpx;
542 - padding: 40rpx; 576 + // padding: 40rpx;
543 margin: 30rpx; 577 margin: 30rpx;
544 margin-bottom: 0; 578 margin-bottom: 0;
545 position: relative; 579 position: relative;
......
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-28 13:32:48 4 + * @LastEditTime: 2025-10-28 16:04:30
5 * @FilePath: /lls_program/src/pages/FamilyRank/index.vue 5 * @FilePath: /lls_program/src/pages/FamilyRank/index.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
42 <view v-if="!loading" class="rank-date relative"> 42 <view v-if="!loading" class="rank-date relative">
43 <!-- <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> --> 43 <!-- <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> -->
44 <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> 44 <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>
45 - <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> 45 + <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>
46 </view> 46 </view>
47 47
48 <!-- 参与家庭数量显示 --> 48 <!-- 参与家庭数量显示 -->
...@@ -154,7 +154,18 @@ ...@@ -154,7 +154,18 @@
154 <view class="no-data-text">暂无助力排行榜更多数据</view> 154 <view class="no-data-text">暂无助力排行榜更多数据</view>
155 </view> --> 155 </view> -->
156 156
157 - <!-- 弹幕显示助力榜内容 --> 157 + </view>
158 +
159 + <!-- 弹幕显示助力榜内容 -->
160 + <view v-if="activeTab === 'support'" class="danmu-section mt-8">
161 + <NativeDanmuComponent
162 + :container-height="1200"
163 + :show-controls="true"
164 + :track-count="7"
165 + @danmu-click="handleDanmuClick"
166 + @danmu-hover="handleDanmuHover"
167 + ref="danmuRef"
168 + />
158 </view> 169 </view>
159 170
160 <!-- 我的排名悬浮卡片 --> 171 <!-- 我的排名悬浮卡片 -->
...@@ -209,8 +220,8 @@ import { ref, computed, onMounted } from 'vue' ...@@ -209,8 +220,8 @@ import { ref, computed, onMounted } from 'vue'
209 import Taro from '@tarojs/taro' 220 import Taro from '@tarojs/taro'
210 import { IconFont } from '@nutui/icons-vue-taro'; 221 import { IconFont } from '@nutui/icons-vue-taro';
211 import BackToTop from '@/components/BackToTop.vue' 222 import BackToTop from '@/components/BackToTop.vue'
223 +import NativeDanmuComponent from '@/components/NativeDanmuComponent.vue'
212 // import NumberRoll from '@/components/NumberRoll.vue' 224 // import NumberRoll from '@/components/NumberRoll.vue'
213 -import vueDanmaku from 'vue-danmaku'
214 // 默认头像 225 // 默认头像
215 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' 226 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'
216 const supportImg = 'https://cdn.ipadbiz.cn/lls_prog/images/support_img_1.png' 227 const supportImg = 'https://cdn.ipadbiz.cn/lls_prog/images/support_img_1.png'
...@@ -268,6 +279,26 @@ const handleRankAskClick = () => { ...@@ -268,6 +279,26 @@ const handleRankAskClick = () => {
268 } 279 }
269 280
270 /** 281 /**
282 + * 弹幕组件相关
283 + */
284 +const danmuRef = ref(null)
285 +
286 +// 处理弹幕点击事件
287 +const handleDanmuClick = (familyData) => {
288 + console.log('弹幕点击:', familyData)
289 + Taro.showToast({
290 + title: `点击了${familyData.familyName}`,
291 + icon: 'none',
292 + duration: 2000
293 + })
294 +}
295 +
296 +// 处理弹幕悬停事件
297 +const handleDanmuHover = (familyData) => {
298 + console.log('弹幕悬停:', familyData)
299 +}
300 +
301 +/**
271 * 触发数字滚动动画 302 * 触发数字滚动动画
272 */ 303 */
273 const triggerNumberRoll = () => { 304 const triggerNumberRoll = () => {
...@@ -1039,7 +1070,5 @@ onMounted(async () => { ...@@ -1039,7 +1070,5 @@ onMounted(async () => {
1039 } 1070 }
1040 } 1071 }
1041 } 1072 }
1042 -
1043 -
1044 } 1073 }
1045 </style> 1074 </style>
......