From e2527c3fb8a6ec95062f4fedc49321bf729047c3 Mon Sep 17 00:00:00 2001 From: alger Date: Wed, 7 May 2025 22:36:52 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20=E4=BF=AE=E6=94=B9=E9=9F=B3?= =?UTF-8?q?=E4=B9=90=E5=88=97=E8=A1=A8=E4=B8=BA=E9=A1=B5=E9=9D=A2=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=93=E8=BE=91=E5=92=8C=E6=AD=8C=E5=8D=95?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E5=8A=A0=E8=BD=BD=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=80=9A=E8=BF=87=E8=B7=AF=E7=94=B1=E8=B7=B3?= =?UTF-8?q?=E8=BD=AC=E5=B1=95=E7=A4=BA=E9=9F=B3=E4=B9=90=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/api/music.ts | 42 + .../components/common/MusicListNavigator.ts | 38 + src/renderer/components/common/PlayBottom.vue | 3 +- src/renderer/components/common/SearchItem.vue | 55 +- .../components/home/RecommendAlbum.vue | 74 +- src/renderer/components/home/TopBanner.vue | 72 +- src/renderer/layout/AppLayout.vue | 18 +- src/renderer/router/other.ts | 11 + src/renderer/store/index.ts | 1 + src/renderer/store/modules/music.ts | 45 + src/renderer/views/artist/detail.vue | 185 +++-- src/renderer/views/list/index.vue | 40 +- src/renderer/views/music/MusicListPage.vue | 773 ++++++++++++++++++ src/renderer/views/user/detail.vue | 41 +- src/renderer/views/user/index.vue | 69 +- 15 files changed, 1208 insertions(+), 259 deletions(-) create mode 100644 src/renderer/components/common/MusicListNavigator.ts create mode 100644 src/renderer/store/modules/music.ts create mode 100644 src/renderer/views/music/MusicListPage.vue diff --git a/src/renderer/api/music.ts b/src/renderer/api/music.ts index f0afbba..8533819 100644 --- a/src/renderer/api/music.ts +++ b/src/renderer/api/music.ts @@ -141,3 +141,45 @@ export const updatePlaylistTracks = (params: { }) => { return request.get('/playlist/tracks', { params }); }; + +/** + * 根据类型获取列表数据 + * @param type 列表类型 album/playlist + * @param id 列表ID + */ +export function getMusicListByType(type: string, id: string) { + if (type === 'album') { + return getAlbumDetail(id); + } else if (type === 'playlist') { + return getPlaylistDetail(id); + } + return Promise.reject(new Error('未知列表类型')); +} + +/** + * 获取专辑详情 + * @param id 专辑ID + */ +export function getAlbumDetail(id: string) { + return request({ + url: '/album', + method: 'get', + params: { + id + } + }); +} + +/** + * 获取歌单详情 + * @param id 歌单ID + */ +export function getPlaylistDetail(id: string) { + return request({ + url: '/playlist/detail', + method: 'get', + params: { + id + } + }); +} diff --git a/src/renderer/components/common/MusicListNavigator.ts b/src/renderer/components/common/MusicListNavigator.ts new file mode 100644 index 0000000..b73d4f3 --- /dev/null +++ b/src/renderer/components/common/MusicListNavigator.ts @@ -0,0 +1,38 @@ +import { Router } from 'vue-router'; +import { useMusicStore } from '@/store/modules/music'; + +/** + * 导航到音乐列表页面的通用方法 + * @param router Vue路由实例 + * @param options 导航选项 + */ +export function navigateToMusicList( + router: Router, + options: { + id?: string | number; + type?: 'album' | 'playlist' | 'dailyRecommend' | string; + name: string; + songList: any[]; + listInfo?: any; + canRemove?: boolean; + } +) { + const musicStore = useMusicStore(); + const { id, type, name, songList, listInfo, canRemove = false } = options; + + // 保存数据到状态管理 + musicStore.setCurrentMusicList(songList, name, listInfo, canRemove); + + // 路由跳转 + if (id) { + router.push({ + name: 'musicList', + params: { id }, + query: { type } + }); + } else { + router.push({ + name: 'musicList' + }); + } +} \ No newline at end of file diff --git a/src/renderer/components/common/PlayBottom.vue b/src/renderer/components/common/PlayBottom.vue index 62536cb..05c33c7 100644 --- a/src/renderer/components/common/PlayBottom.vue +++ b/src/renderer/components/common/PlayBottom.vue @@ -1,11 +1,12 @@ \ No newline at end of file diff --git a/src/renderer/views/user/detail.vue b/src/renderer/views/user/detail.vue index 3214d61..77ba3cd 100644 --- a/src/renderer/views/user/detail.vue +++ b/src/renderer/views/user/detail.vue @@ -63,7 +63,7 @@ class="playlist-item" :class="setAnimationClass('animate__fadeInUp')" :style="setAnimationDelay(index, 50)" - @click="showPlaylist(item.id, item.name)" + @click="openPlaylist(item)" >
- - @@ -140,7 +132,7 @@ import { useRoute, useRouter } from 'vue-router'; import { getListDetail } from '@/api/list'; import { getUserDetail, getUserPlaylist, getUserRecord } from '@/api/user'; import SongItem from '@/components/common/SongItem.vue'; -import MusicList from '@/components/MusicList.vue'; +import { navigateToMusicList } from '@/components/common/MusicListNavigator'; import { usePlayerStore } from '@/store/modules/player'; import type { Playlist } from '@/type/listDetail'; import type { IUserDetail } from '@/type/user'; @@ -166,7 +158,6 @@ const recordList = ref([]); const loading = ref(true); // 歌单详情相关 -const isShowList = ref(false); const currentList = ref(); const listLoading = ref(false); @@ -208,21 +199,23 @@ const loadUserData = async () => { } }; -// 展示歌单 -const showPlaylist = async (id: number, name: string) => { - isShowList.value = true; +// 替换显示歌单的方法 +const openPlaylist = (item: any) => { listLoading.value = true; - - try { - currentList.value = { id, name } as Playlist; - const { data } = await getListDetail(id); - currentList.value = data.playlist; - } catch (error) { - console.error('加载歌单详情失败:', error); - message.error('加载歌单详情失败'); - } finally { + + getListDetail(item.id).then(res => { + currentList.value = res.data.playlist; listLoading.value = false; - } + + navigateToMusicList(router, { + id: item.id, + type: 'playlist', + name: item.name, + songList: res.data.playlist.tracks || [], + listInfo: res.data.playlist, + canRemove: false + }); + }); }; // 播放歌曲 diff --git a/src/renderer/views/user/index.vue b/src/renderer/views/user/index.vue index 02a2dee..6993573 100644 --- a/src/renderer/views/user/index.vue +++ b/src/renderer/views/user/index.vue @@ -34,7 +34,7 @@ v-for="(item, index) in playList" :key="index" class="play-list-item" - @click="showPlaylist(item.id, item.name)" + @click="openPlaylist(item)" > - @@ -101,11 +92,10 @@ import { useI18n } from 'vue-i18n'; import { useRouter } from 'vue-router'; import { getListDetail } from '@/api/list'; -import { updatePlaylistTracks } from '@/api/music'; import { getUserDetail, getUserPlaylist, getUserRecord } from '@/api/user'; import PlayBottom from '@/components/common/PlayBottom.vue'; import SongItem from '@/components/common/SongItem.vue'; -import MusicList from '@/components/MusicList.vue'; +import { navigateToMusicList } from '@/components/common/MusicListNavigator'; import { usePlayerStore } from '@/store/modules/player'; import { useUserStore } from '@/store/modules/user'; import type { Playlist } from '@/type/listDetail'; @@ -125,7 +115,6 @@ const playList = ref([]); const recordList = ref(); const infoLoading = ref(false); const mounted = ref(true); -const isShowList = ref(false); const list = ref(); const listLoading = ref(false); const message = useMessage(); @@ -234,47 +223,23 @@ onMounted(() => { checkLoginStatus() && loadData(); }); -// 展示歌单 -const showPlaylist = async (id: number, name: string) => { - isShowList.value = true; +// 替换显示歌单的方法 +const openPlaylist = (item: any) => { listLoading.value = true; - - list.value = { - name, - id - } as Playlist; - await loadPlaylistDetail(id); - listLoading.value = false; -}; - -// 加载歌单详情 -const loadPlaylistDetail = async (id: number) => { - const { data } = await getListDetail(id); - list.value = data.playlist; -}; - -// 从歌单中删除歌曲 -const handleRemoveFromPlaylist = async (songId: number) => { - if (!list.value?.id) return; - - try { - const res = await updatePlaylistTracks({ - op: 'del', - pid: list.value.id, - tracks: songId.toString() + + getListDetail(item.id).then(res => { + list.value = res.data.playlist; + listLoading.value = false; + + navigateToMusicList(router, { + id: item.id, + type: 'playlist', + name: item.name, + songList: res.data.playlist.tracks || [], + listInfo: res.data.playlist, + canRemove: true // 保留可移除功能 }); - - if (res.status === 200) { - message.success(t('user.message.deleteSuccess')); - // 重新加载歌单详情 - await loadPlaylistDetail(list.value.id); - } else { - throw new Error(res.data?.msg || t('user.message.deleteFailed')); - } - } catch (error: any) { - console.error('删除歌曲失败:', error); - message.error(error.message || t('user.message.deleteFailed')); - } + }); }; const handlePlay = () => {