From 5f4b53c167fe1dc22753c1f99e266dac9ca6373f Mon Sep 17 00:00:00 2001 From: alger Date: Wed, 9 Apr 2025 22:27:52 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20=E6=B7=BB=E5=8A=A0=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E6=92=AD=E6=94=BE=E6=AD=8C=E5=8D=95=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E6=92=AD=E6=94=BE=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=BC=82=E6=AD=A5=E5=8A=A0=E8=BD=BD=E5=AE=8C=E6=95=B4=E6=AD=8C?= =?UTF-8?q?=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/components/home/TopBanner.vue | 124 ++++++++++++++++++--- 1 file changed, 111 insertions(+), 13 deletions(-) diff --git a/src/renderer/components/home/TopBanner.vue b/src/renderer/components/home/TopBanner.vue index a9ddecf..2dededd 100644 --- a/src/renderer/components/home/TopBanner.vue +++ b/src/renderer/components/home/TopBanner.vue @@ -61,19 +61,27 @@ >
-
-
- -
-
{{ item.name }}
+ +
+
+ {{ song.name }} +
+
{{ t('common.songCount', { count: item.trackCount }) }}
+
+ +
@@ -142,13 +150,15 @@ import { useI18n } from 'vue-i18n'; import { getDayRecommend, getHotSinger } from '@/api/home'; import { getListDetail } from '@/api/list'; +import { getMusicDetail } from '@/api/music'; import { getUserPlaylist } from '@/api/user'; import MusicList from '@/components/MusicList.vue'; import { useArtist } from '@/hooks/useArtist'; -import { useUserStore } from '@/store'; +import { usePlayerStore, useUserStore } from '@/store'; import { IDayRecommend } from '@/type/day_recommend'; import { Playlist } from '@/type/list'; import type { IListDetail } from '@/type/listDetail'; +import { SongResult } from '@/type/music'; import type { IHotSinger } from '@/type/singer'; import { getImgUrl, @@ -159,6 +169,7 @@ import { } from '@/utils'; const userStore = useUserStore(); +const playerStore = usePlayerStore(); const { t } = useI18n(); @@ -293,6 +304,93 @@ const toPlaylist = async (id: number) => { } }; +// 添加直接播放歌单的方法 +const handlePlayPlaylist = async (id: number) => { + try { + // 先显示加载状态 + playlistLoading.value = true; + + // 获取歌单详情 + const { data } = await getListDetail(id); + + if (data?.playlist) { + // 先使用已有的tracks开始播放(这些是已经在歌单详情中返回的前几首歌曲) + if (data.playlist.tracks?.length > 0) { + // 格式化歌曲列表 + const initialSongs = data.playlist.tracks.map((track) => ({ + ...track, + source: 'netease', + picUrl: track.al.picUrl + })) as unknown as SongResult[]; + + // 设置播放列表 + playerStore.setPlayList(initialSongs); + + // 开始播放第一首 + await playerStore.setPlay(initialSongs[0]); + + // 如果有trackIds,异步加载完整歌单 + if (data.playlist.trackIds?.length > initialSongs.length) { + loadFullPlaylist(data.playlist.trackIds, initialSongs); + } + } + } + + // 关闭加载状态 + playlistLoading.value = false; + } catch (error) { + console.error('播放歌单失败:', error); + playlistLoading.value = false; + } +}; + +// 异步加载完整歌单 +const loadFullPlaylist = async (trackIds: { id: number }[], initialSongs: SongResult[]) => { + try { + // 获取已加载歌曲的ID集合,避免重复加载 + const loadedIds = new Set(initialSongs.map((song) => song.id)); + + // 筛选出未加载的ID + const unloadedTrackIds = trackIds + .filter((item) => !loadedIds.has(item.id as number)) + .map((item) => item.id); + + if (unloadedTrackIds.length === 0) return; + + // 分批获取歌曲详情,每批最多获取500首 + const batchSize = 500; + const allSongs = [...initialSongs]; + + for (let i = 0; i < unloadedTrackIds.length; i += batchSize) { + const batchIds = unloadedTrackIds.slice(i, i + batchSize); + if (batchIds.length > 0) { + try { + const { data: songsData } = await getMusicDetail(batchIds); + if (songsData?.songs?.length) { + const formattedSongs = songsData.songs.map((item) => ({ + ...item, + source: 'netease', + picUrl: item.al.picUrl + })) as unknown as SongResult[]; + + allSongs.push(...formattedSongs); + } + } catch (error) { + console.error('获取批次歌曲详情失败:', error); + } + } + } + + // 更新完整的播放列表但保持当前播放的歌曲不变 + if (allSongs.length > initialSongs.length) { + console.log('更新播放列表,总歌曲数:', allSongs.length); + playerStore.setPlayList(allSongs); + } + } catch (error) { + console.error('加载完整歌单失败:', error); + } +}; + // 监听登录状态 watchEffect(() => { if (userStore.user) { @@ -416,18 +514,12 @@ const getPlaylistGridClass = (length: number) => { &:hover { transform: translateY(-5px); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); - .user-play-item-overlay { - opacity: 1; - } } img { @apply absolute inset-0 w-full h-full object-cover; } } - &-overlay { - @apply absolute inset-0 bg-black bg-opacity-30 flex items-center justify-center opacity-0 transition-opacity duration-300; - } &-title { @apply absolute top-0 left-0 right-0 p-2 bg-gradient-to-b from-black/70 to-transparent z-10; &-name { @@ -435,11 +527,17 @@ const getPlaylistGridClass = (length: number) => { } } &-count { - @apply absolute bottom-2 right-2 z-10; + @apply absolute bottom-2 left-2 z-10; &-tag { @apply px-2 py-0.5 text-xs text-white bg-black/50 backdrop-blur-sm rounded-full; } } + &-direct-play { + @apply absolute bottom-2 right-2 z-20 w-10 h-10 rounded-full bg-green-600 hover:bg-green-700 flex items-center justify-center cursor-pointer transform scale-90 hover:scale-100 transition-all; + &:hover { + @apply shadow-lg; + } + } &-play-btn { @apply flex items-center justify-center; transform: scale(0.8);