feat: 重构心动模式与私人FM播放逻辑

- 心动模式从播放模式循环中独立,移至 SearchBar 作为独立按钮
- 新增私人FM自动续播:播放结束后自动获取下一首
- 播放列表设置时自动清除FM模式标志
- 顺序播放模式播放到最后一首后正确停止
- 新增获取关注歌手新歌 API
- 补充心动模式相关 i18n 翻译
This commit is contained in:
alger
2026-03-22 16:49:00 +08:00
parent 7f0b3c6469
commit 2b8378bbae
12 changed files with 127 additions and 38 deletions
+32 -1
View File
@@ -467,13 +467,44 @@ const setupAudioListeners = () => {
};
// 监听结束
audioService.on('end', () => {
audioService.on('end', async () => {
console.log('音频播放结束事件触发');
clearInterval();
if (getPlayerStore().playMode === 1) {
// 单曲循环模式
replayMusic();
} else if (getPlayerStore().isFmPlaying) {
// 私人FM模式:自动获取下一首
try {
const { getPersonalFM } = await import('@/api/home');
const res = await getPersonalFM();
const songs = res.data?.data;
if (Array.isArray(songs) && songs.length > 0) {
const song = songs[0];
const fmSong = {
id: song.id,
name: song.name,
picUrl: song.al?.picUrl || song.album?.picUrl,
ar: song.artists || song.ar,
al: song.al || song.album,
source: 'netease' as const,
song,
...song,
playLoading: false
} as any;
const { usePlaylistStore } = await import('@/store/modules/playlist');
const playlistStore = usePlaylistStore();
playlistStore.setPlayList([fmSong], false, false);
getPlayerStore().isFmPlaying = true; // setPlayList 会清除,需重设
await getPlayerStore().handlePlayMusic(fmSong, true);
} else {
getPlayerStore().setIsPlay(false);
}
} catch (error) {
console.error('FM自动播放下一首失败:', error);
getPlayerStore().setIsPlay(false);
}
} else {
// 顺序播放、列表循环、随机播放模式都使用统一的nextPlay方法
getPlayerStore().nextPlay();
+1 -5
View File
@@ -14,7 +14,7 @@ export function usePlayMode() {
// 当前播放模式
const playMode = computed(() => playerStore.playMode);
// 播放模式图标
// 播放模式图标(心动模式已移至 SearchBar,不参与循环切换)
const playModeIcon = computed(() => {
switch (playMode.value) {
case 0:
@@ -23,8 +23,6 @@ export function usePlayMode() {
return 'ri-repeat-one-line';
case 2:
return 'ri-shuffle-line';
case 3:
return 'ri-heart-pulse-line';
default:
return 'ri-repeat-2-line';
}
@@ -39,8 +37,6 @@ export function usePlayMode() {
return t('player.playBar.playMode.loop');
case 2:
return t('player.playBar.playMode.random');
case 3:
return t('player.playBar.intelligenceMode.title');
default:
return t('player.playBar.playMode.sequence');
}