starmusic-pc
1/**
2 * 搜索模块(迁移自 lx-music-mobile/src/core/search/)
3 * 内置源搜索 + 搜索历史/热搜
4 */
5import { getSearchSourceList, getSourceSdk, getSourceTipSearch } from './music-sdk/index.js'
6import { getData, saveData } from './data.js'
7import { STORAGE_KEYS } from './constants.js'
8
9/** 获取搜索来源列表 */
10export const getSearchSources = () => {
11 const list = getSearchSourceList()
12 return [...list, { id: 'all', name: '综合搜索' }]
13}
14
15/**
16 * 搜索音乐
17 * @param {string} text 搜索词
18 * @param {number} page 页码(从 1 开始)
19 * @param {string} sourceId 源 id 或 'all'
20 * @returns {Promise<{list: Array, allPage: number, total: number, source: string}>}
21 */
22export const search = async (text, page = 1, sourceId = 'kw') => {
23 if (!text) return { list: [], allPage: 0, total: 0, source: sourceId }
24
25 if (sourceId === 'all') {
26 // 综合搜索:并行搜索所有源
27 const sources = getSearchSourceList()
28 const tasks = sources.map((source) =>
29 getSourceSdk(source.id)
30 .search(text, page, 25)
31 .catch(() => null),
32 )
33 const results = (await Promise.all(tasks)).filter((r) => r)
34 const allList = []
35 const seenIds = new Set()
36 for (const result of results) {
37 for (const item of result.list) {
38 const key = `${item.source}_${item.songmid}`
39 if (seenIds.has(key)) continue
40 seenIds.add(key)
41 allList.push(item)
42 }
43 }
44 return {
45 list: allList,
46 allPage: Math.max(...results.map((r) => r.allPage || 1), 1),
47 total: allList.length,
48 source: 'all',
49 }
50 }
51
52 const sdk = getSourceSdk(sourceId)
53 if (!sdk || !sdk.search) throw new Error('该源暂不支持搜索')
54 return sdk.search(text, page, 25)
55}
56
57/** 获取热搜 */
58export const getHotSearch = async (sourceId = 'kw') => {
59 const sdk = getSourceSdk(sourceId)
60 if (!sdk || !sdk.getHotSearch) throw new Error('该源暂不支持热搜')
61 return sdk.getHotSearch()
62}
63
64/**
65 * 获取搜索建议(输入联想下拉候选词)
66 * @param {string} sourceId 源 id(默认 'kw',参考项目实际启用的联想源)
67 * @param {string} keyword 已输入的关键词
68 * @returns {Promise<string[]>} 候选词数组;失败或源不支持时返回 []
69 */
70export const getMusicTip = async (sourceId = 'kw', keyword) => {
71 if (!keyword || !String(keyword).trim()) return []
72 return getSourceTipSearch(sourceId, String(keyword).trim()).catch(() => [])
73}
74
75// ============ 搜索历史 ============
76export const getSearchHistory = () => getData(STORAGE_KEYS.SEARCH_HISTORY, [])
77
78export const addHistoryWord = (word) => {
79 const list = getSearchHistory()
80 const index = list.indexOf(word)
81 if (index > -1) list.splice(index, 1)
82 list.unshift(word)
83 const newList = list.slice(0, 30)
84 saveData(STORAGE_KEYS.SEARCH_HISTORY, newList)
85 return newList
86}
87
88export const removeHistoryWord = (word) => {
89 const list = getSearchHistory().filter((w) => w !== word)
90 saveData(STORAGE_KEYS.SEARCH_HISTORY, list)
91 return list
92}
93
94export const clearHistoryList = () => {
95 saveData(STORAGE_KEYS.SEARCH_HISTORY, [])
96 return []
97}