Merge branch 'main' into fix/downloadurl

This commit is contained in:
Alger
2025-05-22 22:15:51 +08:00
committed by GitHub
6 changed files with 123 additions and 27 deletions

View File

@@ -6,7 +6,9 @@ export default {
addToPlaylist: 'Add to Playlist', addToPlaylist: 'Add to Playlist',
favorite: 'Like', favorite: 'Like',
unfavorite: 'Unlike', unfavorite: 'Unlike',
removeFromPlaylist: 'Remove from Playlist' removeFromPlaylist: 'Remove from Playlist',
dislike: 'Dislike',
undislike: 'Undislike',
}, },
message: { message: {
downloading: 'Downloading, please wait...', downloading: 'Downloading, please wait...',
@@ -14,5 +16,13 @@ export default {
downloadQueued: 'Added to download queue', downloadQueued: 'Added to download queue',
addedToNextPlay: 'Added to play next', addedToNextPlay: 'Added to play next',
getUrlFailed: 'Failed to get music download URL, please check if logged in' getUrlFailed: 'Failed to get music download URL, please check if logged in'
},
dialog: {
dislike:{
title: 'Dislike',
content: 'Are you sure you want to dislike this song?',
positiveText: 'Dislike',
negativeText: 'Cancel'
}
} }
}; };

View File

@@ -6,7 +6,9 @@ export default {
addToPlaylist: '添加到歌单', addToPlaylist: '添加到歌单',
favorite: '喜欢', favorite: '喜欢',
unfavorite: '取消喜欢', unfavorite: '取消喜欢',
removeFromPlaylist: '从歌单中删除' removeFromPlaylist: '从歌单中删除',
dislike: '不喜欢',
undislike: '取消不喜欢',
}, },
message: { message: {
downloading: '正在下载中,请稍候...', downloading: '正在下载中,请稍候...',
@@ -14,5 +16,13 @@ export default {
downloadQueued: '已加入下载队列', downloadQueued: '已加入下载队列',
addedToNextPlay: '已添加到下一首播放', addedToNextPlay: '已添加到下一首播放',
getUrlFailed: '获取音乐下载地址失败,请检查是否登录' getUrlFailed: '获取音乐下载地址失败,请检查是否登录'
},
dialog: {
dislike: {
title: '提示!',
content: '确认不喜欢这首歌吗?再次进入将从每日推荐中排除。',
positiveText: '不喜欢',
negativeText: '取消'
}
} }
}; };

View File

@@ -134,7 +134,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import type { MenuOption } from 'naive-ui'; import type { MenuOption } from 'naive-ui';
import { NEllipsis, NImage, useMessage } from 'naive-ui'; import { NEllipsis, NImage, useMessage, useDialog } from 'naive-ui';
import { computed, h, inject, ref, useTemplateRef } from 'vue'; import { computed, h, inject, ref, useTemplateRef } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@@ -306,7 +306,13 @@ const dropdownOptions = computed<MenuOption[]>(() => {
h('i', { h('i', {
class: `iconfont ${isFavorite.value ? 'ri-heart-fill text-red-500' : 'ri-heart-line'}` class: `iconfont ${isFavorite.value ? 'ri-heart-fill text-red-500' : 'ri-heart-line'}`
}) })
} },
// 不喜欢
{
label: isDislike.value ? t('songItem.menu.undislike') : t('songItem.menu.dislike'),
key: 'dislike',
icon: () => h('i', { class: `iconfont ${isDislike.value ? 'ri-dislike-fill text-green-500': 'ri-dislike-line'}` })
},
]; ];
if (props.canRemove) { if (props.canRemove) {
@@ -342,18 +348,30 @@ const handleMenuClick = (e: MouseEvent) => {
const handleSelect = (key: string | number) => { const handleSelect = (key: string | number) => {
showDropdown.value = false; showDropdown.value = false;
if (key === 'download') { switch (key) {
downloadMusic(props.item); case 'download':
} else if (key === 'playNext') { downloadMusic();
handlePlayNext(); break;
} else if (key === 'addToPlaylist') { case 'playNext':
openPlaylistDrawer?.(props.item.id); handlePlayNext();
} else if (key === 'favorite') { break;
toggleFavorite(new Event('click')); case 'addToPlaylist':
} else if (key === 'play') { openPlaylistDrawer?.(props.item.id);
playMusicEvent(props.item); break;
} else if (key === 'remove') { case 'favorite':
emits('remove-song', props.item.id); toggleFavorite(new Event('click'));
break;
case 'play':
playMusicEvent(props.item);
break;
case 'remove':
emits('remove-song', props.item.id);
break;
case 'dislike':
toggleDislike(new Event('click'));
break;
default:
break;
} }
}; };
@@ -395,6 +413,12 @@ const isFavorite = computed(() => {
return playerStore.favoriteList.includes(numericId); return playerStore.favoriteList.includes(numericId);
}); });
const isDislike = computed(() => {
// 将id转换为number兼容B站视频ID
const numericId = typeof props.item.id ==='string'? parseInt(props.item.id, 10) : props.item.id;
return playerStore.dislikeList.includes(numericId);
})
// 切换收藏状态 // 切换收藏状态
const toggleFavorite = async (e: Event) => { const toggleFavorite = async (e: Event) => {
e.stopPropagation(); e.stopPropagation();
@@ -407,6 +431,24 @@ const toggleFavorite = async (e: Event) => {
playerStore.addToFavorite(numericId); playerStore.addToFavorite(numericId);
} }
}; };
const dialog = useDialog();
const toggleDislike = async (e: Event) => {
e.stopPropagation();
if (isDislike.value) {
playerStore.removeFromDislikeList(props.item.id);
return;
}
dialog.warning({
title: t('songItem.dialog.dislike.title'),
content: t('songItem.dialog.dislike.content'),
positiveText: t('songItem.dialog.dislike.positiveText'),
negativeText: t('songItem.dialog.dislike.negativeText'),
onPositiveClick: () => {
playerStore.addToDislikeList(props.item.id);
}
});
}
// 切换选择状态 // 切换选择状态
const toggleSelect = () => { const toggleSelect = () => {

View File

@@ -31,7 +31,7 @@
<div class="mt-2"> <div class="mt-2">
<p <p
v-for="item in dayRecommendData?.dailySongs.slice(0, 5)" v-for="item in getDisplayDaySongs.slice(0, 5)"
:key="item.id" :key="item.id"
class="text-el" class="text-el"
> >
@@ -250,13 +250,16 @@ const loadArtistData = async () => {
// 加载不需要登录的数据 // 加载不需要登录的数据
const loadNonUserData = async () => { const loadNonUserData = async () => {
try { try {
// 获取每日推荐
// 获取每日推荐 try {
try {
const { const {
data: { data: dayRecommend } data: { data: dayRecommend }
} = await getDayRecommend(); } = await getDayRecommend();
dayRecommendData.value = dayRecommend as unknown as IDayRecommend; const dayRecommendSource = dayRecommend as unknown as IDayRecommend;
dayRecommendData.value = {
...dayRecommendSource,
dailySongs: dayRecommendSource.dailySongs.filter((song: any) =>!playerStore.dislikeList.includes(song.id))
};
} catch (error) { } catch (error) {
console.error('获取每日推荐失败:', error); console.error('获取每日推荐失败:', error);
} }
@@ -288,6 +291,12 @@ const loadUserData = async () => {
const handleArtistClick = (id: number) => { const handleArtistClick = (id: number) => {
navigateToArtist(id); navigateToArtist(id);
}; };
const getDisplayDaySongs = computed(() => {
if(!dayRecommendData.value){
return [];
}
return dayRecommendData.value.dailySongs.filter((song) => !playerStore.dislikeList.includes(song.id));
})
const showDayRecommend = () => { const showDayRecommend = () => {
if (!dayRecommendData.value?.dailySongs) return; if (!dayRecommendData.value?.dailySongs) return;
@@ -295,7 +304,7 @@ const showDayRecommend = () => {
navigateToMusicList(router, { navigateToMusicList(router, {
type: 'dailyRecommend', type: 'dailyRecommend',
name: t('comp.recommendSinger.songlist'), name: t('comp.recommendSinger.songlist'),
songList: dayRecommendData.value.dailySongs, songList: getDisplayDaySongs.value,
canRemove: false canRemove: false
}); });
}; };

View File

@@ -394,6 +394,7 @@ export const usePlayerStore = defineStore('player', () => {
const playMode = ref(getLocalStorageItem('playMode', 0)); const playMode = ref(getLocalStorageItem('playMode', 0));
const musicFull = ref(false); const musicFull = ref(false);
const favoriteList = ref<Array<number | string>>(getLocalStorageItem('favoriteList', [])); const favoriteList = ref<Array<number | string>>(getLocalStorageItem('favoriteList', []));
const dislikeList = ref<Array<number | string>>(getLocalStorageItem('dislikeList', []));
const savedPlayProgress = ref<number | undefined>(); const savedPlayProgress = ref<number | undefined>();
const showSleepTimer = ref(false); // 定时弹窗 const showSleepTimer = ref(false); // 定时弹窗
// 添加播放列表抽屉状态 // 添加播放列表抽屉状态
@@ -1037,6 +1038,16 @@ export const usePlayerStore = defineStore('player', () => {
localStorage.setItem('favoriteList', JSON.stringify(favoriteList.value)); localStorage.setItem('favoriteList', JSON.stringify(favoriteList.value));
}; };
const addToDislikeList = (id: number | string) => {
dislikeList.value.push(id);
localStorage.setItem('dislikeList', JSON.stringify(dislikeList.value));
}
const removeFromDislikeList = (id: number | string) => {
dislikeList.value = dislikeList.value.filter(existingId => existingId!== id);
localStorage.setItem('dislikeList', JSON.stringify(dislikeList.value));
}
const removeFromPlayList = (id: number | string) => { const removeFromPlayList = (id: number | string) => {
const index = playList.value.findIndex((item) => item.id === id); const index = playList.value.findIndex((item) => item.id === id);
if (index === -1) return; if (index === -1) return;
@@ -1330,6 +1341,7 @@ export const usePlayerStore = defineStore('player', () => {
musicFull, musicFull,
savedPlayProgress, savedPlayProgress,
favoriteList, favoriteList,
dislikeList,
playListDrawerVisible, playListDrawerVisible,
// 定时关闭相关 // 定时关闭相关
@@ -1364,6 +1376,8 @@ export const usePlayerStore = defineStore('player', () => {
addToFavorite, addToFavorite,
removeFromFavorite, removeFromFavorite,
removeFromPlayList, removeFromPlayList,
addToDislikeList,
removeFromDislikeList,
playAudio, playAudio,
reparseCurrentSong, reparseCurrentSong,
setPlayListDrawerVisible, setPlayListDrawerVisible,

View File

@@ -238,6 +238,11 @@ onMounted(() => {
}); });
// 从 pinia 或路由参数获取数据 // 从 pinia 或路由参数获取数据
// 从路由参数获取
const routeId = route.params.id as string;
const routeType = route.query.type as string;
const initData = () => { const initData = () => {
// 优先从 pinia 获取数据 // 优先从 pinia 获取数据
if (musicStore.currentMusicList) { if (musicStore.currentMusicList) {
@@ -251,9 +256,7 @@ const initData = () => {
return; return;
} }
// 从路由参数获取
const routeId = route.params.id as string;
const routeType = route.query.type as string;
if (routeId) { if (routeId) {
// 这里根据 type 和 id 加载数据 // 这里根据 type 和 id 加载数据
@@ -323,14 +326,22 @@ const getCoverImgUrl = computed(() => {
return ''; return '';
}); });
const getDisplaySongs = computed(() => {
if(routeType === 'dailyRecommend') {
return displayedSongs.value.filter((song) => !playerStore.dislikeList.includes(song.id));
}else {
return displayedSongs.value;
}
})
// 过滤歌曲列表 // 过滤歌曲列表
const filteredSongs = computed(() => { const filteredSongs = computed(() => {
if (!searchKeyword.value) { if (!searchKeyword.value) {
return displayedSongs.value; return getDisplaySongs.value;
} }
const keyword = searchKeyword.value.toLowerCase().trim(); const keyword = searchKeyword.value.toLowerCase().trim();
return displayedSongs.value.filter((song) => { return getDisplaySongs.value.filter((song) => {
const songName = song.name?.toLowerCase() || ''; const songName = song.name?.toLowerCase() || '';
const albumName = song.al?.name?.toLowerCase() || ''; const albumName = song.al?.name?.toLowerCase() || '';
const artists = song.ar || song.artists || []; const artists = song.ar || song.artists || [];