Skip to content

Commit e2527c3

Browse files
committed
✨ feat: 修改音乐列表为页面,优化专辑和歌单详情加载逻辑,支持通过路由跳转展示音乐列表
1 parent 3ca7e9a commit e2527c3

File tree

15 files changed

+1205
-256
lines changed

15 files changed

+1205
-256
lines changed

src/renderer/api/music.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,45 @@ export const updatePlaylistTracks = (params: {
141141
}) => {
142142
return request.get('/playlist/tracks', { params });
143143
};
144+
145+
/**
146+
* 根据类型获取列表数据
147+
* @param type 列表类型 album/playlist
148+
* @param id 列表ID
149+
*/
150+
export function getMusicListByType(type: string, id: string) {
151+
if (type === 'album') {
152+
return getAlbumDetail(id);
153+
} else if (type === 'playlist') {
154+
return getPlaylistDetail(id);
155+
}
156+
return Promise.reject(new Error('未知列表类型'));
157+
}
158+
159+
/**
160+
* 获取专辑详情
161+
* @param id 专辑ID
162+
*/
163+
export function getAlbumDetail(id: string) {
164+
return request({
165+
url: '/album',
166+
method: 'get',
167+
params: {
168+
id
169+
}
170+
});
171+
}
172+
173+
/**
174+
* 获取歌单详情
175+
* @param id 歌单ID
176+
*/
177+
export function getPlaylistDetail(id: string) {
178+
return request({
179+
url: '/playlist/detail',
180+
method: 'get',
181+
params: {
182+
id
183+
}
184+
});
185+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Router } from 'vue-router';
2+
import { useMusicStore } from '@/store/modules/music';
3+
4+
/**
5+
* 导航到音乐列表页面的通用方法
6+
* @param router Vue路由实例
7+
* @param options 导航选项
8+
*/
9+
export function navigateToMusicList(
10+
router: Router,
11+
options: {
12+
id?: string | number;
13+
type?: 'album' | 'playlist' | 'dailyRecommend' | string;
14+
name: string;
15+
songList: any[];
16+
listInfo?: any;
17+
canRemove?: boolean;
18+
}
19+
) {
20+
const musicStore = useMusicStore();
21+
const { id, type, name, songList, listInfo, canRemove = false } = options;
22+
23+
// 保存数据到状态管理
24+
musicStore.setCurrentMusicList(songList, name, listInfo, canRemove);
25+
26+
// 路由跳转
27+
if (id) {
28+
router.push({
29+
name: 'musicList',
30+
params: { id },
31+
query: { type }
32+
});
33+
} else {
34+
router.push({
35+
name: 'musicList'
36+
});
37+
}
38+
}

src/renderer/components/common/PlayBottom.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<template>
2-
<div v-if="isPlay" class="bottom" :style="{ height }"></div>
2+
<div v-if="isPlay && !isMobile" class="bottom" :style="{ height }"></div>
33
</template>
44

55
<script setup lang="ts">
66
import { computed } from 'vue';
77
88
import { usePlayerStore } from '@/store/modules/player';
9+
import { isMobile } from '@/utils';
910
1011
const playerStore = usePlayerStore();
1112
const isPlay = computed(() => playerStore.playMusicUrl);

src/renderer/components/common/SearchItem.vue

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,6 @@
2121
<span>{{ item.size }}</span>
2222
</div>
2323

24-
<music-list
25-
v-if="['专辑', 'playlist'].includes(item.type)"
26-
v-model:show="showPop"
27-
:name="item.name"
28-
:song-list="songList"
29-
:list-info="listInfo"
30-
:cover="false"
31-
:z-index="zIndex"
32-
/>
3324
<mv-player
3425
v-if="item.type === 'mv'"
3526
v-model:show="showPop"
@@ -46,8 +37,8 @@ import { audioService } from '@/services/audioService';
4637
import { usePlayerStore } from '@/store/modules/player';
4738
import { IMvItem } from '@/type/mv';
4839
import { getImgUrl } from '@/utils';
49-
50-
import MusicList from '../MusicList.vue';
40+
import { useRouter } from 'vue-router';
41+
import { useMusicStore } from '@/store/modules/music';
5142
5243
const props = withDefaults(
5344
defineProps<{
@@ -72,6 +63,8 @@ const showPop = ref(false);
7263
const listInfo = ref<any>(null);
7364
7465
const playerStore = usePlayerStore();
66+
const router = useRouter();
67+
const musicStore = useMusicStore();
7568
7669
const getCurrentMv = () => {
7770
return {
@@ -83,7 +76,6 @@ const getCurrentMv = () => {
8376
const handleClick = async () => {
8477
listInfo.value = null;
8578
if (props.item.type === '专辑') {
86-
showPop.value = true;
8779
const res = await getAlbum(props.item.id);
8880
songList.value = res.data.songs.map((song: any) => {
8981
song.al.picUrl = song.al.picUrl || props.item.picUrl;
@@ -97,16 +89,41 @@ const handleClick = async () => {
9789
},
9890
description: res.data.album.description
9991
};
100-
}
101-
102-
if (props.item.type === 'playlist') {
103-
showPop.value = true;
92+
93+
// 保存数据到store
94+
musicStore.setCurrentMusicList(
95+
songList.value,
96+
props.item.name,
97+
listInfo.value,
98+
false
99+
);
100+
101+
// 使用路由跳转
102+
router.push({
103+
name: 'musicList',
104+
params: { id: props.item.id },
105+
query: { type: 'album' }
106+
});
107+
} else if (props.item.type === 'playlist') {
104108
const res = await getListDetail(props.item.id);
105109
songList.value = res.data.playlist.tracks;
106110
listInfo.value = res.data.playlist;
107-
}
108-
109-
if (props.item.type === 'mv') {
111+
112+
// 保存数据到store
113+
musicStore.setCurrentMusicList(
114+
songList.value,
115+
props.item.name,
116+
listInfo.value,
117+
false
118+
);
119+
120+
// 使用路由跳转
121+
router.push({
122+
name: 'musicList',
123+
params: { id: props.item.id },
124+
query: { type: 'playlist' }
125+
});
126+
} else if (props.item.type === 'mv') {
110127
handleShowMv();
111128
}
112129
};

src/renderer/components/home/RecommendAlbum.vue

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,19 @@
2222
</div>
2323
</template>
2424
</div>
25-
<music-list
26-
v-model:show="showMusic"
27-
:name="albumName"
28-
:song-list="songList"
29-
:cover="true"
30-
:loading="loadingList"
31-
:list-info="albumInfo"
32-
/>
3325
</div>
3426
</template>
3527

3628
<script lang="ts" setup>
3729
import { onMounted, ref } from 'vue';
3830
import { useI18n } from 'vue-i18n';
31+
import { useRouter } from 'vue-router';
3932
4033
import { getNewAlbum } from '@/api/home';
4134
import { getAlbum } from '@/api/list';
42-
import MusicList from '@/components/MusicList.vue';
43-
import type { IAlbumNew } from '@/type/album';
4435
import { getImgUrl, setAnimationClass, setAnimationDelay } from '@/utils';
36+
import { navigateToMusicList } from '@/components/common/MusicListNavigator';
37+
import type { IAlbumNew } from '@/type/album';
4538
4639
const { t } = useI18n();
4740
const albumData = ref<IAlbumNew>();
@@ -50,33 +43,42 @@ const loadAlbumList = async () => {
5043
albumData.value = data;
5144
};
5245
53-
const showMusic = ref(false);
54-
const songList = ref([]);
55-
const albumName = ref('');
56-
const loadingList = ref(false);
57-
const albumInfo = ref<any>({});
46+
const router = useRouter();
47+
5848
const handleClick = async (item: any) => {
59-
songList.value = [];
60-
albumInfo.value = {};
61-
albumName.value = item.name;
62-
loadingList.value = true;
63-
showMusic.value = true;
64-
const res = await getAlbum(item.id);
65-
const { songs, album } = res.data;
66-
songList.value = songs.map((song: any) => {
67-
song.al.picUrl = song.al.picUrl || album.picUrl;
68-
song.picUrl = song.al.picUrl || album.picUrl || song.picUrl;
69-
return song;
70-
});
71-
albumInfo.value = {
72-
...album,
73-
creator: {
74-
avatarUrl: album.artist.img1v1Url,
75-
nickname: `${album.artist.name} - ${album.company}`
76-
},
77-
description: album.description
78-
};
79-
loadingList.value = false;
49+
openAlbum(item);
50+
};
51+
52+
const openAlbum = async (album: any) => {
53+
if (!album) return;
54+
55+
try {
56+
const res = await getAlbum(album.id);
57+
const { songs, album: albumInfo } = res.data;
58+
59+
const formattedSongs = songs.map((song: any) => {
60+
song.al.picUrl = song.al.picUrl || albumInfo.picUrl;
61+
song.picUrl = song.al.picUrl || albumInfo.picUrl || song.picUrl;
62+
return song;
63+
});
64+
65+
navigateToMusicList(router, {
66+
id: album.id,
67+
type: 'album',
68+
name: album.name,
69+
songList: formattedSongs,
70+
listInfo: {
71+
...albumInfo,
72+
creator: {
73+
avatarUrl: albumInfo.artist.img1v1Url,
74+
nickname: `${albumInfo.artist.name} - ${albumInfo.company}`
75+
},
76+
description: albumInfo.description
77+
}
78+
});
79+
} catch (error) {
80+
console.error('获取专辑详情失败:', error);
81+
}
8082
};
8183
8284
onMounted(() => {

0 commit comments

Comments
 (0)