diff --git a/package.json b/package.json index fe71ce9..bebfe14 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ ] }, "dependencies": { - "@electron-toolkit/preload": "^3.0.1", + "@electron-toolkit/preload": "^3.0.2", "@electron-toolkit/utils": "^4.0.0", "@unblockneteasemusic/server": "^0.27.8-patch.1", "cors": "^2.8.5", @@ -56,7 +56,7 @@ "@electron-toolkit/tsconfig": "^1.0.1", "@eslint/js": "^9.31.0", "@rushstack/eslint-patch": "^1.10.3", - "@tailwindcss/postcss7-compat": "^2.2.4", + "@types/howler": "^2.2.12", "@types/node": "^20.14.8", "@types/tinycolor2": "^1.4.6", @@ -68,15 +68,15 @@ "@vue/eslint-config-typescript": "^14.5.0", "@vue/runtime-core": "^3.5.0", "@vueuse/core": "^11.3.0", - "@vueuse/electron": "^11.3.0", + "@vueuse/electron": "^13.8.0", "animate.css": "^4.1.1", "autoprefixer": "^10.4.20", "axios": "^1.7.7", "cross-env": "^7.0.3", - "electron": "^35.2.0", - "electron-builder": "^25.1.8", - "electron-vite": "^3.1.0", - "eslint": "^9.0.0", + "electron": "^37.4.0", + "electron-builder": "^26.0.12", + "electron-vite": "^4.0.0", + "eslint": "^9.34.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", "eslint-plugin-prettier": "^5.5.3", @@ -91,7 +91,7 @@ "naive-ui": "^2.41.0", "pinia": "^3.0.1", "pinyin-match": "^1.2.6", - "postcss": "^8.5.3", + "postcss": "^8.4.47", "prettier": "^3.6.2", "remixicon": "^4.6.0", "sass": "^1.86.0", diff --git a/src/renderer/components/common/PlaylistDrawer.vue b/src/renderer/components/common/PlaylistDrawer.vue index 4c9e21c..5f759da 100644 --- a/src/renderer/components/common/PlaylistDrawer.vue +++ b/src/renderer/components/common/PlaylistDrawer.vue @@ -117,6 +117,7 @@ import { createPlaylist, updatePlaylistTracks } from '@/api/music'; import { getUserPlaylist } from '@/api/user'; import { useUserStore } from '@/store'; import { getImgUrl } from '@/utils'; +import { hasPermission, getLoginErrorMessage } from '@/utils/auth'; const store = useUserStore(); const { t } = useI18n(); @@ -160,6 +161,13 @@ const fetchUserPlaylists = async () => { return; } + // 检查是否有真实登录权限 + if (!hasPermission(true)) { + message.error(getLoginErrorMessage(true)); + emit('update:modelValue', false); + return; + } + const res = await getUserPlaylist(user.userId, 999); if (res.data?.playlist) { playlists.value = res.data.playlist.filter((item: any) => item.userId === user.userId); @@ -173,6 +181,13 @@ const fetchUserPlaylists = async () => { // 添加到歌单 const handleAddToPlaylist = async (playlist: any) => { if (!props.songId) return; + + // 检查是否有真实登录权限 + if (!hasPermission(true)) { + message.error(getLoginErrorMessage(true)); + return; + } + try { const res = await updatePlaylistTracks({ op: 'add', @@ -200,6 +215,12 @@ const handleCreatePlaylist = async () => { return; } + // 检查是否有真实登录权限 + if (!hasPermission(true)) { + message.error(getLoginErrorMessage(true)); + return; + } + try { creating.value = true; diff --git a/src/renderer/components/common/songItemCom/SongItemDropdown.vue b/src/renderer/components/common/songItemCom/SongItemDropdown.vue index 7ab9b07..db42901 100644 --- a/src/renderer/components/common/songItemCom/SongItemDropdown.vue +++ b/src/renderer/components/common/songItemCom/SongItemDropdown.vue @@ -21,6 +21,7 @@ import { useI18n } from 'vue-i18n'; import type { SongResult } from '@/types/music'; import { getImgUrl, isElectron } from '@/utils'; +import { hasPermission } from '@/utils/auth'; const { t } = useI18n(); @@ -121,6 +122,8 @@ const renderSongPreview = () => { // 下拉菜单选项 const dropdownOptions = computed(() => { + const hasRealAuth = hasPermission(true); + const options: MenuOption[] = [ { key: 'header', @@ -153,7 +156,8 @@ const dropdownOptions = computed(() => { { label: t('songItem.menu.addToPlaylist'), key: 'addToPlaylist', - icon: () => h('i', { class: 'iconfont ri-folder-add-line' }) + icon: () => h('i', { class: 'iconfont ri-folder-add-line' }), + disabled: !hasRealAuth }, { label: props.isFavorite ? t('songItem.menu.unfavorite') : t('songItem.menu.favorite'), @@ -162,6 +166,7 @@ const dropdownOptions = computed(() => { h('i', { class: `iconfont ${props.isFavorite ? 'ri-heart-fill text-red-500' : 'ri-heart-line'}` }) + // 收藏功能不禁用,UID登录时可以本地收藏/取消收藏 }, { label: props.isDislike ? t('songItem.menu.undislike') : t('songItem.menu.dislike'), diff --git a/src/renderer/store/modules/player.ts b/src/renderer/store/modules/player.ts index d73afbe..5da47e7 100644 --- a/src/renderer/store/modules/player.ts +++ b/src/renderer/store/modules/player.ts @@ -12,6 +12,7 @@ import { audioService } from '@/services/audioService'; import type { ILyric, ILyricText, SongResult } from '@/types/music'; import { type Platform } from '@/types/music'; import { getImgUrl } from '@/utils'; +import { hasPermission } from '@/utils/auth'; import { getImageLinearBackground } from '@/utils/linearColor'; import { useSettingsStore } from './settings'; @@ -1282,9 +1283,17 @@ export const usePlayerStore = defineStore('player', () => { ); if (!isAlreadyInList) { + // 先添加到本地收藏列表 favoriteList.value.push(id); localStorage.setItem('favoriteList', JSON.stringify(favoriteList.value)); - typeof id === 'number' && useUserStore().user && likeSong(id, true); + // 只有在有真实登录权限时才调用API + if (typeof id === 'number' && useUserStore().user && hasPermission(true)) { + try { + await likeSong(id, true); + } catch (error) { + console.error('收藏歌曲API调用失败:', error); + } + } } }; @@ -1295,8 +1304,16 @@ export const usePlayerStore = defineStore('player', () => { (existingId) => !isBilibiliIdMatch(existingId, id) ); } else { + // 先从本地收藏列表中移除 favoriteList.value = favoriteList.value.filter((existingId) => existingId !== id); - useUserStore().user && likeSong(Number(id), false); + // 只有在有真实登录权限时才调用API + if (typeof id === 'number' && useUserStore().user && hasPermission(true)) { + try { + await likeSong(id, false); + } catch (error) { + console.error('取消收藏歌曲API调用失败:', error); + } + } } localStorage.setItem('favoriteList', JSON.stringify(favoriteList.value)); }; diff --git a/src/renderer/views/music/MusicListPage.vue b/src/renderer/views/music/MusicListPage.vue index 5c33efb..4bb01a3 100644 --- a/src/renderer/views/music/MusicListPage.vue +++ b/src/renderer/views/music/MusicListPage.vue @@ -234,6 +234,7 @@ import { useDownload } from '@/hooks/useDownload'; import { useMusicStore, usePlayerStore, useRecommendStore } from '@/store'; import { SongResult } from '@/types/music'; import { getImgUrl, isElectron, isMobile, setAnimationClass } from '@/utils'; +import { getLoginErrorMessage, hasPermission } from '@/utils/auth'; const { t } = useI18n(); const route = useRoute(); @@ -816,6 +817,12 @@ const checkCollectionStatus = () => { const toggleCollect = async () => { if (!listInfo.value?.id) return; + // 检查是否有真实登录权限 + if (!hasPermission(true)) { + message.error(getLoginErrorMessage(true)); + return; + } + try { loadingList.value = true; const tVal = isCollected.value ? 2 : 1; // 1:收藏, 2:取消收藏