mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-05 07:20:50 +08:00
feat: 添加心动模式播放
This commit is contained in:
@@ -66,7 +66,17 @@ export default {
|
||||
favorite: 'Favorite {name}',
|
||||
unFavorite: 'Unfavorite {name}',
|
||||
playbackSpeed: 'Playback Speed',
|
||||
advancedControls: 'Advanced Controls'
|
||||
advancedControls: 'Advanced Controls',
|
||||
intelligenceMode: {
|
||||
title: 'Intelligence Mode',
|
||||
needCookieLogin: 'Please login with Cookie method to use Intelligence Mode',
|
||||
noFavoritePlaylist: 'Favorite playlist not found',
|
||||
noLikedSongs: 'You have no liked songs yet',
|
||||
loading: 'Loading Intelligence Mode',
|
||||
success: 'Loaded {count} songs',
|
||||
failed: 'Failed to get Intelligence Mode list',
|
||||
error: 'Intelligence Mode error'
|
||||
}
|
||||
},
|
||||
eq: {
|
||||
title: 'Equalizer',
|
||||
|
||||
@@ -67,7 +67,17 @@ export default {
|
||||
unFavorite: '{name}をお気に入りから削除しました',
|
||||
miniPlayBar: 'ミニ再生バー',
|
||||
playbackSpeed: '再生速度',
|
||||
advancedControls: 'その他の設定'
|
||||
advancedControls: 'その他の設定',
|
||||
intelligenceMode: {
|
||||
title: 'インテリジェンスモード',
|
||||
needCookieLogin: 'Cookie方式でログインしてからインテリジェンスモードを使用してください',
|
||||
noFavoritePlaylist: '「お気に入りの音楽」プレイリストが見つかりません',
|
||||
noLikedSongs: 'まだ「いいね」した楽曲がありません',
|
||||
loading: 'インテリジェンスモードを読み込み中',
|
||||
success: '{count} 曲を読み込みました',
|
||||
failed: 'インテリジェンスモードのリスト取得に失敗しました',
|
||||
error: 'インテリジェンスモードの再生でエラーが発生しました'
|
||||
}
|
||||
},
|
||||
eq: {
|
||||
title: 'イコライザー',
|
||||
|
||||
@@ -67,7 +67,17 @@ export default {
|
||||
unFavorite: '{name} 즐겨찾기 해제됨',
|
||||
miniPlayBar: '미니 재생바',
|
||||
playbackSpeed: '재생 속도',
|
||||
advancedControls: '고급 설정'
|
||||
advancedControls: '고급 설정',
|
||||
intelligenceMode: {
|
||||
title: '인텔리전스 모드',
|
||||
needCookieLogin: '쿠키 방식으로 로그인한 후 인텔리전스 모드를 사용할 수 있습니다',
|
||||
noFavoritePlaylist: '내가 좋아하는 음악 재생목록을 찾을 수 없습니다',
|
||||
noLikedSongs: '아직 좋아한 노래가 없습니다',
|
||||
loading: '인텔리전스 모드를 불러오는 중',
|
||||
success: '총 {count}곡을 불러왔습니다',
|
||||
failed: '인텔리전스 모드 목록을 가져오는 데 실패했습니다',
|
||||
error: '인텔리전스 모드 재생 오류'
|
||||
}
|
||||
},
|
||||
eq: {
|
||||
title: '이퀄라이저',
|
||||
|
||||
@@ -67,7 +67,17 @@ export default {
|
||||
unFavorite: '已取消收藏{name}',
|
||||
miniPlayBar: '迷你播放栏',
|
||||
playbackSpeed: '播放速度',
|
||||
advancedControls: '更多设置s'
|
||||
advancedControls: '更多设置',
|
||||
intelligenceMode: {
|
||||
title: '心动模式',
|
||||
needCookieLogin: '请使用 Cookie 方式登录后使用心动模式',
|
||||
noFavoritePlaylist: '未找到我喜欢的音乐歌单',
|
||||
noLikedSongs: '您还没有喜欢的歌曲',
|
||||
loading: '正在加载心动模式',
|
||||
success: '已加载 {count} 首歌曲',
|
||||
failed: '获取心动模式列表失败',
|
||||
error: '心动模式播放出错'
|
||||
}
|
||||
},
|
||||
eq: {
|
||||
title: '均衡器',
|
||||
|
||||
@@ -67,7 +67,17 @@ export default {
|
||||
unFavorite: '已取消收藏{name}',
|
||||
miniPlayBar: '迷你播放列',
|
||||
playbackSpeed: '播放速度',
|
||||
advancedControls: '更多設定s'
|
||||
advancedControls: '更多設定',
|
||||
intelligenceMode: {
|
||||
title: '心動模式',
|
||||
needCookieLogin: '請使用 Cookie 方式登入後使用心動模式',
|
||||
noFavoritePlaylist: '未找到我喜歡的音樂歌單',
|
||||
noLikedSongs: '您還沒有喜歡的歌曲',
|
||||
loading: '正在載入心動模式',
|
||||
success: '已載入 {count} 首歌曲',
|
||||
failed: '取得心動模式清單失敗',
|
||||
error: '心動模式播放出錯'
|
||||
}
|
||||
},
|
||||
eq: {
|
||||
title: '等化器',
|
||||
|
||||
@@ -210,3 +210,15 @@ export function getHistoryRecommendSongs(date: string) {
|
||||
params: { date }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 心动模式/智能播放
|
||||
* @param params id: 歌曲id, pid: 歌单id, sid: 要开始播放的歌曲id(可选)
|
||||
*/
|
||||
export function getIntelligenceList(params: { id: number; pid: number; sid?: number }) {
|
||||
return request({
|
||||
url: '/playmode/intelligence/list',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@
|
||||
<i class="ri-arrow-down-s-line"></i>
|
||||
</div>
|
||||
<div class="side-button" @click="togglePlayMode">
|
||||
<i :class="playModeIcon"></i>
|
||||
<i :class="[playModeIcon, { 'intelligence-active': playMode === 3 }]"></i>
|
||||
</div>
|
||||
<div class="main-button prev" @click="prevSong">
|
||||
<i class="ri-skip-back-fill"></i>
|
||||
@@ -382,6 +382,7 @@ import {
|
||||
useLyricProgress
|
||||
} from '@/hooks/MusicHook';
|
||||
import { useArtist } from '@/hooks/useArtist';
|
||||
import { usePlayMode } from '@/hooks/usePlayMode';
|
||||
import { usePlayerStore } from '@/store/modules/player';
|
||||
import { DEFAULT_LYRIC_CONFIG, LyricConfig } from '@/types/lyric';
|
||||
import { getImgUrl, secondToMinute } from '@/utils';
|
||||
@@ -394,19 +395,9 @@ const playerStore = usePlayerStore();
|
||||
// 播放控制相关
|
||||
const play = computed(() => playerStore.isPlay);
|
||||
const playIcon = computed(() => (play.value ? 'ri-pause-fill' : 'ri-play-fill'));
|
||||
const playMode = computed(() => playerStore.playMode);
|
||||
const playModeIcon = computed(() => {
|
||||
switch (playMode.value) {
|
||||
case 0:
|
||||
return 'ri-repeat-line';
|
||||
case 1:
|
||||
return 'ri-repeat-one-line';
|
||||
case 2:
|
||||
return 'ri-shuffle-line';
|
||||
default:
|
||||
return 'ri-repeat-line';
|
||||
}
|
||||
});
|
||||
|
||||
// 播放模式
|
||||
const { playMode, playModeIcon, playModeText, togglePlayMode: togglePlayModeBase } = usePlayMode();
|
||||
// 打开播放列表
|
||||
const showPlaylist = () => {
|
||||
playerStore.setPlayListDrawerVisible(true);
|
||||
@@ -963,12 +954,8 @@ const prevSong = () => {
|
||||
};
|
||||
|
||||
const togglePlayMode = () => {
|
||||
playerStore.togglePlayMode();
|
||||
showBottomToast(
|
||||
[t('player.playMode.sequence'), t('player.playMode.loop'), t('player.playMode.random')][
|
||||
playMode.value
|
||||
]
|
||||
);
|
||||
togglePlayModeBase();
|
||||
showBottomToast(playModeText.value);
|
||||
};
|
||||
|
||||
const closeMusicFull = () => {
|
||||
@@ -1525,6 +1512,10 @@ const getWordStyle = (lineIndex: number, _wordIndex: number, word: any) => {
|
||||
i {
|
||||
@apply text-2xl;
|
||||
color: var(--text-color-primary);
|
||||
|
||||
&.intelligence-active {
|
||||
@apply text-green-500;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
@@ -105,15 +105,23 @@
|
||||
</div>
|
||||
<n-tooltip v-if="!isMobile" trigger="hover" :z-index="9999999">
|
||||
<template #trigger>
|
||||
<i class="iconfont" :class="playModeIcon" @click="togglePlayMode"></i>
|
||||
<i
|
||||
class="iconfont"
|
||||
:class="[playModeIcon, { 'intelligence-active': playMode === 3 }]"
|
||||
@click="togglePlayMode"
|
||||
></i>
|
||||
</template>
|
||||
{{ playModeText }}
|
||||
</n-tooltip>
|
||||
<n-tooltip v-if="!isMobile" trigger="hover" :z-index="9999999">
|
||||
<template #trigger>
|
||||
<i
|
||||
class="iconfont icon-likefill"
|
||||
:class="{ 'like-active': isFavorite }"
|
||||
class="iconfont"
|
||||
:class="{
|
||||
'like-active': isFavorite,
|
||||
'ri-heart-3-fill': isFavorite,
|
||||
'ri-heart-3-line': !isFavorite
|
||||
}"
|
||||
@click="toggleFavorite"
|
||||
></i>
|
||||
</template>
|
||||
@@ -174,6 +182,7 @@ import {
|
||||
textColors
|
||||
} from '@/hooks/MusicHook';
|
||||
import { useArtist } from '@/hooks/useArtist';
|
||||
import { usePlayMode } from '@/hooks/usePlayMode';
|
||||
import { audioService } from '@/services/audioService';
|
||||
import { isBilibiliIdMatch, usePlayerStore } from '@/store/modules/player';
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
@@ -282,38 +291,10 @@ const handleVolumeWheel = (e: WheelEvent) => {
|
||||
};
|
||||
|
||||
// 播放模式
|
||||
const playMode = computed(() => playerStore.playMode);
|
||||
const playModeIcon = computed(() => {
|
||||
switch (playMode.value) {
|
||||
case 0:
|
||||
return 'ri-repeat-2-line';
|
||||
case 1:
|
||||
return 'ri-repeat-one-line';
|
||||
case 2:
|
||||
return 'ri-shuffle-line';
|
||||
default:
|
||||
return 'ri-repeat-2-line';
|
||||
}
|
||||
});
|
||||
const playModeText = computed(() => {
|
||||
switch (playMode.value) {
|
||||
case 0:
|
||||
return t('player.playBar.playMode.sequence');
|
||||
case 1:
|
||||
return t('player.playBar.playMode.loop');
|
||||
case 2:
|
||||
return t('player.playBar.playMode.random');
|
||||
default:
|
||||
return t('player.playBar.playMode.sequence');
|
||||
}
|
||||
});
|
||||
const { playMode, playModeIcon, playModeText, togglePlayMode } = usePlayMode();
|
||||
|
||||
// 播放速度控制
|
||||
const { playbackRate } = storeToRefs(playerStore);
|
||||
// 切换播放模式
|
||||
const togglePlayMode = () => {
|
||||
playerStore.togglePlayMode();
|
||||
};
|
||||
|
||||
function handleNext() {
|
||||
playerStore.nextPlay();
|
||||
@@ -645,6 +626,10 @@ const openPlayListDrawer = () => {
|
||||
@apply text-red-500 hover:text-red-600 !important;
|
||||
}
|
||||
|
||||
.intelligence-active {
|
||||
@apply text-green-500 hover:text-green-600 !important;
|
||||
}
|
||||
|
||||
.disabled-icon {
|
||||
@apply opacity-50 cursor-not-allowed !important;
|
||||
&:hover {
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
<div class="controls-section">
|
||||
<div class="left-controls">
|
||||
<button class="control-btn small-btn" @click="togglePlayMode">
|
||||
<i class="iconfont" :class="playModeIcon"></i>
|
||||
<i
|
||||
class="iconfont"
|
||||
:class="[playModeIcon, { 'intelligence-active': playMode === 3 }]"
|
||||
></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -73,6 +76,7 @@
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { allTime, nowTime, playMusic } from '@/hooks/MusicHook';
|
||||
import { usePlayMode } from '@/hooks/usePlayMode';
|
||||
import { audioService } from '@/services/audioService';
|
||||
import { usePlayerStore } from '@/store/modules/player';
|
||||
import { secondToMinute } from '@/utils';
|
||||
@@ -93,24 +97,7 @@ const playBarRef = ref<HTMLElement | null>(null);
|
||||
const play = computed(() => playerStore.isPlay);
|
||||
|
||||
// 播放模式
|
||||
const playMode = computed(() => playerStore.playMode);
|
||||
const playModeIcon = computed(() => {
|
||||
switch (playMode.value) {
|
||||
case 0:
|
||||
return 'ri-repeat-2-line';
|
||||
case 1:
|
||||
return 'ri-repeat-one-line';
|
||||
case 2:
|
||||
return 'ri-shuffle-line';
|
||||
default:
|
||||
return 'ri-repeat-2-line';
|
||||
}
|
||||
});
|
||||
|
||||
// 切换播放模式
|
||||
const togglePlayMode = () => {
|
||||
playerStore.togglePlayMode();
|
||||
};
|
||||
const { playMode, playModeIcon, togglePlayMode } = usePlayMode();
|
||||
|
||||
// 音量控制
|
||||
const audioVolume = ref(
|
||||
@@ -527,4 +514,8 @@ onMounted(() => {
|
||||
color: var(--fill-color);
|
||||
text-shadow: 0 0 8px var(--fill-color-transparent);
|
||||
}
|
||||
|
||||
.intelligence-active {
|
||||
@apply text-green-500;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -758,7 +758,6 @@ export const getLrcTimeRange = (index: number) => ({
|
||||
watch(
|
||||
() => lrcArray.value,
|
||||
(newLrcArray) => {
|
||||
console.log('lrcArray.value', lrcArray.value);
|
||||
if (newLrcArray.length > 0 && isElectron && isLyricWindowOpen.value) {
|
||||
sendLyricToWin();
|
||||
}
|
||||
|
||||
60
src/renderer/hooks/usePlayMode.ts
Normal file
60
src/renderer/hooks/usePlayMode.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { usePlayerStore } from '@/store/modules/player';
|
||||
|
||||
/**
|
||||
* 播放模式相关的 Hook
|
||||
* 提供播放模式的图标、文本和切换功能
|
||||
*/
|
||||
export function usePlayMode() {
|
||||
const { t } = useI18n();
|
||||
const playerStore = usePlayerStore();
|
||||
|
||||
// 当前播放模式
|
||||
const playMode = computed(() => playerStore.playMode);
|
||||
|
||||
// 播放模式图标
|
||||
const playModeIcon = computed(() => {
|
||||
switch (playMode.value) {
|
||||
case 0:
|
||||
return 'ri-repeat-2-line';
|
||||
case 1:
|
||||
return 'ri-repeat-one-line';
|
||||
case 2:
|
||||
return 'ri-shuffle-line';
|
||||
case 3:
|
||||
return 'ri-heart-pulse-line';
|
||||
default:
|
||||
return 'ri-repeat-2-line';
|
||||
}
|
||||
});
|
||||
|
||||
// 播放模式文本
|
||||
const playModeText = computed(() => {
|
||||
switch (playMode.value) {
|
||||
case 0:
|
||||
return t('player.playBar.playMode.sequence');
|
||||
case 1:
|
||||
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');
|
||||
}
|
||||
});
|
||||
|
||||
// 切换播放模式
|
||||
const togglePlayMode = () => {
|
||||
playerStore.togglePlayMode();
|
||||
};
|
||||
|
||||
return {
|
||||
playMode,
|
||||
playModeIcon,
|
||||
playModeText,
|
||||
togglePlayMode
|
||||
};
|
||||
}
|
||||
@@ -853,10 +853,6 @@ class AudioService {
|
||||
const isLoading = this.isLoading();
|
||||
const contextRunning = Howler.ctx && Howler.ctx.state === 'running';
|
||||
|
||||
console.log(
|
||||
`实际播放状态检查: playing=${isPlaying}, loading=${isLoading}, contextRunning=${contextRunning}`
|
||||
);
|
||||
|
||||
// 只有在三个条件都满足时才认为是真正在播放
|
||||
return isPlaying && !isLoading && contextRunning;
|
||||
} catch (error) {
|
||||
|
||||
@@ -330,8 +330,6 @@ export const loadLrc = async (id: string | number): Promise<ILyric> => {
|
||||
});
|
||||
}
|
||||
|
||||
console.log('lyrics', lyrics);
|
||||
|
||||
return {
|
||||
lrcTimeArray: times,
|
||||
lrcArray: lyrics,
|
||||
@@ -537,6 +535,13 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
// 原始播放列表 - 保存切换到随机模式前的顺序
|
||||
const originalPlayList = ref<SongResult[]>(getLocalStorageItem('originalPlayList', []));
|
||||
|
||||
// 心动模式状态
|
||||
const isIntelligenceMode = ref(getLocalStorageItem('isIntelligenceMode', false));
|
||||
const intelligenceModeInfo = ref<{
|
||||
playlistId: number;
|
||||
seedSongId: number;
|
||||
} | null>(getLocalStorageItem('intelligenceModeInfo', null));
|
||||
|
||||
// 通用洗牌函数 - Fisher-Yates 算法
|
||||
const performShuffle = (list: SongResult[], currentSong?: SongResult): SongResult[] => {
|
||||
if (list.length <= 1) return [...list];
|
||||
@@ -960,7 +965,19 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
musicFull.value = value;
|
||||
};
|
||||
|
||||
const setPlayList = (list: SongResult[], keepIndex: boolean = false) => {
|
||||
const setPlayList = (
|
||||
list: SongResult[],
|
||||
keepIndex: boolean = false,
|
||||
fromIntelligenceMode: boolean = false
|
||||
) => {
|
||||
// 如果不是从心动模式调用,则清除心动模式状态
|
||||
if (!fromIntelligenceMode && isIntelligenceMode.value) {
|
||||
isIntelligenceMode.value = false;
|
||||
intelligenceModeInfo.value = null;
|
||||
localStorage.removeItem('isIntelligenceMode');
|
||||
localStorage.removeItem('intelligenceModeInfo');
|
||||
}
|
||||
|
||||
if (list.length === 0) {
|
||||
playList.value = [];
|
||||
playListIndex.value = 0;
|
||||
@@ -1341,10 +1358,21 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
// 节流
|
||||
const prevPlay = useThrottleFn(_prevPlay, 500);
|
||||
|
||||
const togglePlayMode = () => {
|
||||
const newMode = (playMode.value + 1) % 3;
|
||||
const togglePlayMode = async () => {
|
||||
const userStore = useUserStore();
|
||||
const wasIntelligence = playMode.value === 3;
|
||||
const newMode = (playMode.value + 1) % 4; // 扩展到4种模式
|
||||
const wasRandom = playMode.value === 2;
|
||||
const isRandom = newMode === 2;
|
||||
const isIntelligence = newMode === 3;
|
||||
|
||||
// 如果要切换到心动模式,但用户未使用cookie登录,则跳过心动模式
|
||||
if (isIntelligence && (!userStore.user || userStore.loginType !== 'cookie')) {
|
||||
console.log('跳过心动模式:需要cookie登录');
|
||||
playMode.value = 0; // 跳到顺序模式
|
||||
localStorage.setItem('playMode', JSON.stringify(playMode.value));
|
||||
return;
|
||||
}
|
||||
|
||||
playMode.value = newMode;
|
||||
localStorage.setItem('playMode', JSON.stringify(playMode.value));
|
||||
@@ -1356,10 +1384,25 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
}
|
||||
|
||||
// 当从随机模式切换出去时,恢复原始顺序
|
||||
if (!isRandom && wasRandom) {
|
||||
if (!isRandom && wasRandom && !isIntelligence) {
|
||||
restoreOriginalOrder();
|
||||
console.log('切换出随机模式,恢复原始顺序');
|
||||
}
|
||||
|
||||
// 当切换到心动模式时,触发心动模式播放
|
||||
if (isIntelligence && !wasIntelligence) {
|
||||
console.log('切换到心动模式');
|
||||
await playIntelligenceMode();
|
||||
}
|
||||
|
||||
// 当从心动模式切换出去时,清除心动模式状态
|
||||
if (!isIntelligence && wasIntelligence) {
|
||||
console.log('退出心动模式');
|
||||
isIntelligenceMode.value = false;
|
||||
intelligenceModeInfo.value = null;
|
||||
localStorage.setItem('isIntelligenceMode', JSON.stringify(false));
|
||||
localStorage.removeItem('intelligenceModeInfo');
|
||||
}
|
||||
};
|
||||
|
||||
const addToFavorite = async (id: number | string) => {
|
||||
@@ -1444,9 +1487,12 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
const settingStore = useSettingsStore();
|
||||
const savedPlayList = getLocalStorageItem('playList', []);
|
||||
const savedPlayMusic = getLocalStorageItem<SongResult | null>('currentPlayMusic', null);
|
||||
// 恢复心动模式状态
|
||||
const savedIntelligenceMode = getLocalStorageItem('isIntelligenceMode', false);
|
||||
|
||||
if (savedPlayList.length > 0) {
|
||||
setPlayList(savedPlayList);
|
||||
// 如果是心动模式,保持状态
|
||||
setPlayList(savedPlayList, false, savedIntelligenceMode);
|
||||
|
||||
// 重启后恢复随机播放状态
|
||||
if (playMode.value === 2) {
|
||||
@@ -1747,6 +1793,86 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
return newVolume;
|
||||
};
|
||||
|
||||
// 心动模式播放
|
||||
const playIntelligenceMode = async () => {
|
||||
const userStore = useUserStore();
|
||||
const { t } = i18n.global;
|
||||
|
||||
// 检查是否使用cookie登录
|
||||
if (!userStore.user || userStore.loginType !== 'cookie') {
|
||||
message.warning(t('player.playBar.intelligenceMode.needCookieLogin'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取用户歌单列表
|
||||
if (userStore.playList.length === 0) {
|
||||
await userStore.initializePlaylist();
|
||||
}
|
||||
|
||||
// 找到"我喜欢的音乐"歌单(通常是第一个歌单)
|
||||
const favoritePlaylist = userStore.playList.find(
|
||||
(pl: any) => pl.userId === userStore.user?.userId && pl.specialType === 5
|
||||
);
|
||||
|
||||
if (!favoritePlaylist) {
|
||||
message.warning(t('player.playBar.intelligenceMode.noFavoritePlaylist'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取喜欢的歌曲列表
|
||||
const likedListRes = await getLikedList(userStore.user.userId);
|
||||
const likedIds = likedListRes.data?.ids || [];
|
||||
|
||||
if (likedIds.length === 0) {
|
||||
message.warning(t('player.playBar.intelligenceMode.noLikedSongs'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 随机选择一首歌曲
|
||||
const randomSongId = likedIds[Math.floor(Math.random() * likedIds.length)];
|
||||
|
||||
// 调用心动模式API
|
||||
const { getIntelligenceList } = await import('@/api/music');
|
||||
const res = await getIntelligenceList({
|
||||
id: randomSongId,
|
||||
pid: favoritePlaylist.id
|
||||
});
|
||||
|
||||
if (res.data?.data && res.data.data.length > 0) {
|
||||
const intelligenceSongs = res.data.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.songInfo.name,
|
||||
picUrl: item.songInfo.al?.picUrl,
|
||||
source: 'netease' as Platform,
|
||||
song: item.songInfo,
|
||||
...item.songInfo,
|
||||
playLoading: false
|
||||
}));
|
||||
|
||||
// 设置心动模式状态
|
||||
isIntelligenceMode.value = true;
|
||||
intelligenceModeInfo.value = {
|
||||
playlistId: favoritePlaylist.id,
|
||||
seedSongId: randomSongId
|
||||
};
|
||||
playMode.value = 3; // 设置播放模式为心动模式
|
||||
localStorage.setItem('isIntelligenceMode', JSON.stringify(true));
|
||||
localStorage.setItem('intelligenceModeInfo', JSON.stringify(intelligenceModeInfo.value));
|
||||
localStorage.setItem('playMode', JSON.stringify(playMode.value));
|
||||
|
||||
// 替换播放列表并开始播放
|
||||
await setPlayList(intelligenceSongs, false, true);
|
||||
await handlePlayMusic(intelligenceSongs[0], true);
|
||||
} else {
|
||||
message.error(t('player.playBar.intelligenceMode.failed'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('心动模式播放失败:', error);
|
||||
message.error(t('player.playBar.intelligenceMode.error'));
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
play,
|
||||
isPlay,
|
||||
@@ -1812,6 +1938,11 @@ export const usePlayerStore = defineStore('player', () => {
|
||||
originalPlayList,
|
||||
shufflePlayList,
|
||||
restoreOriginalOrder,
|
||||
preloadNextSongs
|
||||
preloadNextSongs,
|
||||
|
||||
// 心动模式
|
||||
playIntelligenceMode,
|
||||
isIntelligenceMode,
|
||||
intelligenceModeInfo
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user