hookehuyr

fix(AudioPlayer): 修复音频列表为空时的渲染问题

修复了当音频列表为空时,AudioPlayer组件渲染出错的问题。通过在StudyDetailPage.vue中添加条件渲染,确保只有在音频列表不为空时才渲染AudioPlayer组件。同时,在AudioPlayer.vue中增加了对currentSong和song属性的可选链操作,防止未定义时的错误。
1 <!-- 1 <!--
2 * @Date: 2025-04-07 12:35:35 2 * @Date: 2025-04-07 12:35:35
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-05-08 10:20:49 4 + * @LastEditTime: 2025-05-16 16:50:23
5 * @FilePath: /mlaj/src/components/ui/AudioPlayer.vue 5 * @FilePath: /mlaj/src/components/ui/AudioPlayer.vue
6 * @Description: 音频播放器组件,支持播放控制、进度条调节、音量控制、播放列表等功能 6 * @Description: 音频播放器组件,支持播放控制、进度条调节、音量控制、播放列表等功能
7 --> 7 -->
...@@ -12,13 +12,13 @@ ...@@ -12,13 +12,13 @@
12 <div class="flex flex-col items-center mb-4"> 12 <div class="flex flex-col items-center mb-4">
13 <!-- 歌曲封面 --> 13 <!-- 歌曲封面 -->
14 <div class="w-24 h-24 rounded-lg overflow-hidden mb-2"> 14 <div class="w-24 h-24 rounded-lg overflow-hidden mb-2">
15 - <img :src="currentSong.cover" alt="封面" class="w-full h-full object-cover"> 15 + <img :src="currentSong?.cover" alt="封面" class="w-full h-full object-cover">
16 </div> 16 </div>
17 17
18 <!-- 歌曲信息 --> 18 <!-- 歌曲信息 -->
19 <div class="text-center"> 19 <div class="text-center">
20 - <h3 class="text-base font-medium">{{ currentSong.title }}</h3> 20 + <h3 class="text-base font-medium">{{ currentSong?.title }}</h3>
21 - <p class="text-xs text-gray-500">{{ currentSong.artist }}</p> 21 + <p class="text-xs text-gray-500">{{ currentSong?.artist }}</p>
22 </div> 22 </div>
23 23
24 </div> 24 </div>
...@@ -105,11 +105,11 @@ ...@@ -105,11 +105,11 @@
105 > 105 >
106 <div class="absolute top-0 left-0 right-0 h-[1px] bg-gray-200"></div> 106 <div class="absolute top-0 left-0 right-0 h-[1px] bg-gray-200"></div>
107 <div class="w-16 h-16 rounded-lg overflow-hidden mr-4 flex-shrink-0"> 107 <div class="w-16 h-16 rounded-lg overflow-hidden mr-4 flex-shrink-0">
108 - <img :src="song.cover" alt="封面" class="w-full h-full object-cover"> 108 + <img :src="song?.cover" alt="封面" class="w-full h-full object-cover">
109 </div> 109 </div>
110 <div class="flex-1"> 110 <div class="flex-1">
111 - <div class="font-medium">{{ song.title }}</div> 111 + <div class="font-medium">{{ song?.title }}</div>
112 - <div class="text-sm text-gray-500">{{ song.artist }}</div> 112 + <div class="text-sm text-gray-500">{{ song?.artist }}</div>
113 </div> 113 </div>
114 <font-awesome-icon 114 <font-awesome-icon
115 v-if="index === currentIndex && isPlaying" 115 v-if="index === currentIndex && isPlaying"
...@@ -275,6 +275,7 @@ const handleVolumeChange = (e) => { ...@@ -275,6 +275,7 @@ const handleVolumeChange = (e) => {
275 275
276 // 监听歌曲列表变化 276 // 监听歌曲列表变化
277 watch(() => props.songs, () => { 277 watch(() => props.songs, () => {
278 + console.warn('歌曲列表变化', props.songs);
278 currentIndex.value = 0 279 currentIndex.value = 0
279 loadAudio() 280 loadAudio()
280 }, { deep: true }) 281 }, { deep: true })
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
29 <div v-if="course.course_type === 'audio'" class="w-full relative" 29 <div v-if="course.course_type === 'audio'" class="w-full relative"
30 style="border-bottom: 1px solid #F3F4F6;"> 30 style="border-bottom: 1px solid #F3F4F6;">
31 <!-- 音频播放器 --> 31 <!-- 音频播放器 -->
32 - <AudioPlayer :songs="audioList" /> 32 + <AudioPlayer v-if="audioList.length" :songs="audioList" />
33 </div> 33 </div>
34 <!-- 图片列表展示区域 --> 34 <!-- 图片列表展示区域 -->
35 <div v-if="course.course_type === 'image'" class="w-full relative"> 35 <div v-if="course.course_type === 'image'" class="w-full relative">
...@@ -359,6 +359,18 @@ const handleLessonClick = async (lesson) => { ...@@ -359,6 +359,18 @@ const handleLessonClick = async (lesson) => {
359 course.value = data; 359 course.value = data;
360 courseFile.value = data.file; 360 courseFile.value = data.file;
361 361
362 + // 更新音频列表数据
363 + if (data.course_type === 'audio' && data.file?.list?.length) {
364 + audioList.value = data.file.list.map(item => ({
365 + title: item.title || '未命名音频',
366 + artist: '',
367 + url: item.url,
368 + cover: item.cover || 'https://cdn.ipadbiz.cn/mlaj/images/audio_d_cover.jpg'
369 + }));
370 + } else {
371 + audioList.value = [];
372 + }
373 +
362 // 获取评论列表 374 // 获取评论列表
363 const comment = await getGroupCommentListAPI({ group_id: data.group_id, schedule_id: data.id }); 375 const comment = await getGroupCommentListAPI({ group_id: data.group_id, schedule_id: data.id });
364 if (comment.code) { 376 if (comment.code) {
......