diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index d39c87b..422baa5 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -59,7 +59,7 @@ const navItems = [
{ path: "/", label: "歌单", icon: "home" },
{ path: "/ranking", label: "排行榜", icon: "trophy" },
{ path: "/library", label: "我的音乐", icon: "music" },
- { path: "/demo", label: "演示", icon: "play" },
+ // { path: "/demo", label: "演示", icon: "play" },
] as const
function isActive(path: string) {
diff --git a/src/views/SearchView.vue b/src/views/SearchView.vue
index f7fced4..e1292e6 100644
--- a/src/views/SearchView.vue
+++ b/src/views/SearchView.vue
@@ -17,6 +17,19 @@
+
+
+
+
+
+
+
+
@@ -84,11 +108,15 @@ import { NEmpty, NInput, NSpin, NTabPane, NTabs, NTag, useDialog, useMessage } f
import AppIcon from "@/components/AppIcon.vue"
import MusicCard from "@/components/MusicCard.vue"
import SongTable from "@/components/SongTable.vue"
-import MusicApi, { type MusicSearchPlaylist, type MusicSearchSong } from "@/api/music"
+import MusicApi, {
+ type MusicSearchAlbum,
+ type MusicSearchPlaylist,
+ type MusicSearchSong,
+} from "@/api/music"
import type { PlayListSummary } from "@/api/playlist"
import { hotKeywords, type Song } from "@/mocks/music"
import { usePlayerStore } from "@/stores/player"
-import { useSettingsStore } from "@/stores/settings"
+import { ALL_SOURCES, SOURCE_LABELS, useSettingsStore } from "@/stores/settings"
import { displayCover } from "@/utils/cover"
import Source from "@/types/global"
import { useSearchHistoryStore } from "@/stores/searchHistory"
@@ -100,12 +128,15 @@ const settingsStore = useSettingsStore()
const searchHistoryStore = useSearchHistoryStore()
const keyword = ref("")
const activeTab = ref("song")
+const allSources = ALL_SOURCES
+const selectedSource = ref(settingsStore.defaultSource)
const normalized = computed(() => keyword.value.trim().toLowerCase())
const loading = ref(false)
const songResults = ref([])
const playlistResults = ref([])
+const albumResults = ref([])
let searchTimer: number | undefined
let requestSeq = 0
@@ -119,6 +150,7 @@ watch(normalized, (q) => {
requestSeq += 1
songResults.value = []
playlistResults.value = []
+ albumResults.value = []
loading.value = false
return
}
@@ -130,9 +162,11 @@ watch(normalized, (q) => {
async function doSearch(q: string) {
const seq = ++requestSeq
loading.value = true
- const [songRes, playlistRes] = await Promise.allSettled([
- MusicApi.search(q, "song", settingsStore.enabledSources),
- MusicApi.search(q, "playlist", settingsStore.enabledSources),
+ const sources = [selectedSource.value]
+ const [songRes, playlistRes, albumRes] = await Promise.allSettled([
+ MusicApi.search(q, "song", sources),
+ MusicApi.search(q, "playlist", sources),
+ MusicApi.search(q, "album", sources),
])
if (seq !== requestSeq) return
if (songRes.status === "fulfilled") {
@@ -145,6 +179,11 @@ async function doSearch(q: string) {
} else {
playlistResults.value = []
}
+ if (albumRes.status === "fulfilled") {
+ albumResults.value = (albumRes.value.data.albums ?? []).map(toPlaylist)
+ } else {
+ albumResults.value = []
+ }
loading.value = false
}
@@ -160,7 +199,7 @@ function toSong(item: MusicSearchSong): Song {
}
}
-function toPlaylist(item: MusicSearchPlaylist): PlayListSummary {
+function toPlaylist(item: MusicSearchPlaylist | MusicSearchAlbum): PlayListSummary {
return {
id: item.id,
name: item.name,
@@ -174,6 +213,18 @@ function toPlaylist(item: MusicSearchPlaylist): PlayListSummary {
}
}
+function onSourceChange(source: Source) {
+ settingsStore.setDefaultSource(source)
+ const q = normalized.value
+ if (q) {
+ if (searchTimer !== undefined) {
+ window.clearTimeout(searchTimer)
+ searchTimer = undefined
+ }
+ void doSearch(q)
+ }
+}
+
async function playSearchSong(song: Song) {
const source = (song.source ?? settingsStore.defaultSource) as Source
try {
@@ -182,6 +233,10 @@ async function playSearchSong(song: Song) {
const res = await MusicApi.url(String(song.id), source)
const url = res.data.url
console.log("url: ", url)
+ if (!res) {
+ message.error(`获取直链失败:${song.title}`)
+ return
+ }
playerStore.playSong(song, songResults.value, url)
} catch {
// 拿不到直链时仍切歌,后续可尝试 MusicApi.stream 代理播放
@@ -246,6 +301,14 @@ onBeforeUnmount(() => {
max-width: min(560px, 100%);
}
+.source-bar {
+ margin-top: 18px;
+}
+
+.source-scrollbar {
+ padding-bottom: 8px;
+}
+
.search-icon {
color: var(--app-text-muted);
}