From 2b8378bbae1f60a5d5b241563ecb7d4915c31f2c Mon Sep 17 00:00:00 2001 From: alger Date: Sun, 22 Mar 2026 16:49:00 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20=E9=87=8D=E6=9E=84=E5=BF=83?= =?UTF-8?q?=E5=8A=A8=E6=A8=A1=E5=BC=8F=E4=B8=8E=E7=A7=81=E4=BA=BAFM?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 心动模式从播放模式循环中独立,移至 SearchBar 作为独立按钮 - 新增私人FM自动续播:播放结束后自动获取下一首 - 播放列表设置时自动清除FM模式标志 - 顺序播放模式播放到最后一首后正确停止 - 新增获取关注歌手新歌 API - 补充心动模式相关 i18n 翻译 --- src/i18n/lang/en-US/comp.ts | 4 +- src/i18n/lang/ja-JP/comp.ts | 4 +- src/i18n/lang/ko-KR/comp.ts | 4 +- src/i18n/lang/zh-CN/comp.ts | 4 +- src/i18n/lang/zh-Hant/comp.ts | 4 +- src/renderer/api/artist.ts | 5 +++ src/renderer/hooks/MusicHook.ts | 33 ++++++++++++++- src/renderer/hooks/usePlayMode.ts | 6 +-- src/renderer/layout/components/SearchBar.vue | 41 ++++++++++++++++++ src/renderer/store/modules/player.ts | 14 ++++++- src/renderer/store/modules/playerCore.ts | 2 + src/renderer/store/modules/playlist.ts | 44 +++++++++----------- 12 files changed, 127 insertions(+), 38 deletions(-) diff --git a/src/i18n/lang/en-US/comp.ts b/src/i18n/lang/en-US/comp.ts index 1972e18..bd3a782 100644 --- a/src/i18n/lang/en-US/comp.ts +++ b/src/i18n/lang/en-US/comp.ts @@ -194,7 +194,9 @@ export default { tabPlaylist: 'Playlist', tabMv: 'MV', tabCharts: 'Charts', - cancelSearch: 'Cancel' + cancelSearch: 'Cancel', + intelligenceMode: 'Intelligence Mode', + exitIntelligence: 'Exit Intelligence Mode' }, titleBar: { closeTitle: 'Choose how to close', diff --git a/src/i18n/lang/ja-JP/comp.ts b/src/i18n/lang/ja-JP/comp.ts index d1b0bf0..9352f31 100644 --- a/src/i18n/lang/ja-JP/comp.ts +++ b/src/i18n/lang/ja-JP/comp.ts @@ -194,7 +194,9 @@ export default { tabPlaylist: 'プレイリスト', tabMv: 'MV', tabCharts: 'チャート', - cancelSearch: 'キャンセル' + cancelSearch: 'キャンセル', + intelligenceMode: '心動モード', + exitIntelligence: '心動モードを終了' }, titleBar: { closeTitle: '閉じる方法を選択してください', diff --git a/src/i18n/lang/ko-KR/comp.ts b/src/i18n/lang/ko-KR/comp.ts index 8acb640..1b26f3b 100644 --- a/src/i18n/lang/ko-KR/comp.ts +++ b/src/i18n/lang/ko-KR/comp.ts @@ -193,7 +193,9 @@ export default { tabPlaylist: '플레이리스트', tabMv: 'MV', tabCharts: '차트', - cancelSearch: '취소' + cancelSearch: '취소', + intelligenceMode: '심쿵 모드', + exitIntelligence: '심쿵 모드 종료' }, titleBar: { closeTitle: '닫기 방법을 선택해주세요', diff --git a/src/i18n/lang/zh-CN/comp.ts b/src/i18n/lang/zh-CN/comp.ts index f6a0f98..81ca947 100644 --- a/src/i18n/lang/zh-CN/comp.ts +++ b/src/i18n/lang/zh-CN/comp.ts @@ -187,7 +187,9 @@ export default { tabPlaylist: '播放列表', tabMv: 'MV', tabCharts: '排行榜', - cancelSearch: '取消' + cancelSearch: '取消', + intelligenceMode: '心动模式', + exitIntelligence: '退出心动模式' }, titleBar: { closeTitle: '请选择关闭方式', diff --git a/src/i18n/lang/zh-Hant/comp.ts b/src/i18n/lang/zh-Hant/comp.ts index fd271ce..d422b49 100644 --- a/src/i18n/lang/zh-Hant/comp.ts +++ b/src/i18n/lang/zh-Hant/comp.ts @@ -187,7 +187,9 @@ export default { tabPlaylist: '播放清單', tabMv: 'MV', tabCharts: '排行榜', - cancelSearch: '取消' + cancelSearch: '取消', + intelligenceMode: '心動模式', + exitIntelligence: '退出心動模式' }, titleBar: { closeTitle: '請選擇關閉方式', diff --git a/src/renderer/api/artist.ts b/src/renderer/api/artist.ts index 3b9db85..b92df9f 100644 --- a/src/renderer/api/artist.ts +++ b/src/renderer/api/artist.ts @@ -19,3 +19,8 @@ export const getArtistTopSongs = (params) => { export const getArtistAlbums = (params) => { return request.get('/artist/album', { params }); }; + +// 获取关注歌手新歌 +export const getArtistNewSongs = (limit: number = 20) => { + return request.get('/artist/new/song', { params: { limit } }); +}; diff --git a/src/renderer/hooks/MusicHook.ts b/src/renderer/hooks/MusicHook.ts index 07125ae..dae8c92 100644 --- a/src/renderer/hooks/MusicHook.ts +++ b/src/renderer/hooks/MusicHook.ts @@ -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(); diff --git a/src/renderer/hooks/usePlayMode.ts b/src/renderer/hooks/usePlayMode.ts index a1b0d1f..f951e7b 100644 --- a/src/renderer/hooks/usePlayMode.ts +++ b/src/renderer/hooks/usePlayMode.ts @@ -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'); } diff --git a/src/renderer/layout/components/SearchBar.vue b/src/renderer/layout/components/SearchBar.vue index 146b5c5..aef707f 100644 --- a/src/renderer/layout/components/SearchBar.vue +++ b/src/renderer/layout/components/SearchBar.vue @@ -105,6 +105,24 @@ + + + + {{ + isIntelligenceMode + ? t('comp.searchBar.exitIntelligence') + : t('comp.searchBar.intelligenceMode') + }} + +