mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-05-18 03:17:29 +08:00
fix: electron环境使用kg, 其他环境使用 wy api,独立kg搜索提示 API 到otherApi.ts
This commit is contained in:
@@ -16,6 +16,7 @@ import { setupUpdateHandlers } from './modules/update';
|
|||||||
import { createMainWindow, initializeWindowManager, setAppQuitting } from './modules/window';
|
import { createMainWindow, initializeWindowManager, setAppQuitting } from './modules/window';
|
||||||
import { initWindowSizeManager } from './modules/window-size';
|
import { initWindowSizeManager } from './modules/window-size';
|
||||||
import { startMusicApi } from './server';
|
import { startMusicApi } from './server';
|
||||||
|
import { initializeOtherApi } from './modules/otherApi';
|
||||||
|
|
||||||
// 导入所有图标
|
// 导入所有图标
|
||||||
const iconPath = join(__dirname, '../../resources');
|
const iconPath = join(__dirname, '../../resources');
|
||||||
@@ -38,6 +39,8 @@ function initialize() {
|
|||||||
|
|
||||||
// 初始化文件管理
|
// 初始化文件管理
|
||||||
initializeFileManager();
|
initializeFileManager();
|
||||||
|
// 初始化其他 API (搜索建议等)
|
||||||
|
initializeOtherApi();
|
||||||
// 初始化窗口管理
|
// 初始化窗口管理
|
||||||
initializeWindowManager();
|
initializeWindowManager();
|
||||||
// 初始化字体管理
|
// 初始化字体管理
|
||||||
|
|||||||
@@ -275,28 +275,6 @@ export function initializeFileManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 搜索建议
|
|
||||||
ipcMain.handle('get-search-suggestions', async (_, keyword: string) => {
|
|
||||||
if (!keyword || !keyword.trim()) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
console.log(`[Main Process Proxy] Forwarding suggestion request for: ${keyword}`);
|
|
||||||
const response = await axios.get('http://msearchcdn.kugou.com/new/app/i/search.php', {
|
|
||||||
params: {
|
|
||||||
cmd: 302,
|
|
||||||
keyword: keyword,
|
|
||||||
},
|
|
||||||
timeout: 5000
|
|
||||||
});
|
|
||||||
return response.data;
|
|
||||||
|
|
||||||
} catch (error: any) {
|
|
||||||
console.error('[Main Process Proxy] Failed to fetch search suggestions:', error.message);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { ipcMain } from 'electron';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化其他杂项 API(如搜索建议等)
|
||||||
|
*/
|
||||||
|
export function initializeOtherApi() {
|
||||||
|
// 搜索建议(从酷狗获取)
|
||||||
|
ipcMain.handle('get-search-suggestions', async (_, keyword: string) => {
|
||||||
|
if (!keyword || !keyword.trim()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
console.log(`[Main Process Proxy] Forwarding suggestion request for: ${keyword}`);
|
||||||
|
const response = await axios.get('http://msearchcdn.kugou.com/new/app/i/search.php', {
|
||||||
|
params: {
|
||||||
|
cmd: 302,
|
||||||
|
keyword: keyword
|
||||||
|
},
|
||||||
|
timeout: 5000
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('[Main Process Proxy] Failed to fetch search suggestions:', error.message);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import request from '@/utils/request';
|
|
||||||
import { isElectron } from '@/utils';
|
import { isElectron } from '@/utils';
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
interface IParams {
|
interface IParams {
|
||||||
keywords: string;
|
keywords: string;
|
||||||
@@ -25,6 +25,16 @@ interface KugouSuggestionResponse {
|
|||||||
data: Suggestion[];
|
data: Suggestion[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 网易云搜索建议返回的数据结构(部分字段)
|
||||||
|
interface NeteaseSuggestResult {
|
||||||
|
result?: {
|
||||||
|
songs?: Array<{ name: string }>;
|
||||||
|
artists?: Array<{ name: string }>;
|
||||||
|
albums?: Array<{ name: string }>;
|
||||||
|
};
|
||||||
|
code?: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从酷狗获取搜索建议
|
* 从酷狗获取搜索建议
|
||||||
* @param keyword 搜索关键词
|
* @param keyword 搜索关键词
|
||||||
@@ -44,11 +54,25 @@ export const getSearchSuggestions = async (keyword: string) => {
|
|||||||
console.log('[API] Running in Electron, using IPC proxy.');
|
console.log('[API] Running in Electron, using IPC proxy.');
|
||||||
responseData = await window.api.getSearchSuggestions(keyword);
|
responseData = await window.api.getSearchSuggestions(keyword);
|
||||||
} else {
|
} else {
|
||||||
return [];
|
// 非 Electron 环境下,使用网易云接口
|
||||||
|
const res = await request.get<NeteaseSuggestResult>('/search/suggest', {
|
||||||
|
params: { keywords: keyword }
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = res?.data?.result || {};
|
||||||
|
const names: string[] = [];
|
||||||
|
if (Array.isArray(result.songs)) names.push(...result.songs.map((s) => s.name));
|
||||||
|
if (Array.isArray(result.artists)) names.push(...result.artists.map((a) => a.name));
|
||||||
|
if (Array.isArray(result.albums)) names.push(...result.albums.map((al) => al.name));
|
||||||
|
|
||||||
|
// 去重并截取前10个
|
||||||
|
const unique = Array.from(new Set(names)).slice(0, 10);
|
||||||
|
console.log('[API] getSearchSuggestions: 网易云建议解析成功:', unique);
|
||||||
|
return unique;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseData && Array.isArray(responseData.data)) {
|
if (responseData && Array.isArray(responseData.data)) {
|
||||||
const suggestions = responseData.data.map(item => item.keyword).slice(0, 10);
|
const suggestions = responseData.data.map((item) => item.keyword).slice(0, 10);
|
||||||
console.log('[API] getSearchSuggestions: 成功解析建议:', suggestions);
|
console.log('[API] getSearchSuggestions: 成功解析建议:', suggestions);
|
||||||
return suggestions;
|
return suggestions;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,25 +5,25 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="search-box-input flex-1 relative">
|
<div class="search-box-input flex-1 relative">
|
||||||
<n-popover
|
<n-popover
|
||||||
trigger="manual"
|
trigger="manual"
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
:show="showSuggestions"
|
:show="showSuggestions"
|
||||||
:show-arrow="false"
|
:show-arrow="false"
|
||||||
style="width: 100%; margin-top: 4px;"
|
style="width: 100%; margin-top: 4px"
|
||||||
content-style="padding: 0; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1);"
|
content-style="padding: 0; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1);"
|
||||||
raw
|
raw
|
||||||
>
|
>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-input
|
<n-input
|
||||||
v-model:value="searchValue"
|
v-model:value="searchValue"
|
||||||
size="medium"
|
size="medium"
|
||||||
round
|
round
|
||||||
:placeholder="hotSearchKeyword"
|
:placeholder="hotSearchKeyword"
|
||||||
class="border dark:border-gray-600 border-gray-200"
|
class="border dark:border-gray-600 border-gray-200"
|
||||||
@input="handleInput"
|
@input="handleInput"
|
||||||
@keydown="handleKeydown"
|
@keydown="handleKeydown"
|
||||||
@focus="handleFocus"
|
@focus="handleFocus"
|
||||||
@blur="handleBlur"
|
@blur="handleBlur"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<i class="iconfont icon-search"></i>
|
<i class="iconfont icon-search"></i>
|
||||||
@@ -32,7 +32,9 @@
|
|||||||
<n-dropdown trigger="hover" :options="searchTypeOptions" @select="selectSearchType">
|
<n-dropdown trigger="hover" :options="searchTypeOptions" @select="selectSearchType">
|
||||||
<div class="w-20 px-3 flex justify-between items-center">
|
<div class="w-20 px-3 flex justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
{{ searchTypeOptions.find((item) => item.key === searchStore.searchType)?.label }}
|
{{
|
||||||
|
searchTypeOptions.find((item) => item.key === searchStore.searchType)?.label
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
<i class="iconfont icon-xiasanjiaoxing"></i>
|
<i class="iconfont icon-xiasanjiaoxing"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -42,17 +44,17 @@
|
|||||||
</template>
|
</template>
|
||||||
<!-- ==================== 搜索建议列表 ==================== -->
|
<!-- ==================== 搜索建议列表 ==================== -->
|
||||||
<div class="search-suggestions-panel">
|
<div class="search-suggestions-panel">
|
||||||
<n-scrollbar style="max-height: 300px;">
|
<n-scrollbar style="max-height: 300px">
|
||||||
<div v-if="suggestionsLoading" class="suggestion-item loading">
|
<div v-if="suggestionsLoading" class="suggestion-item loading">
|
||||||
<n-spin size="small" />
|
<n-spin size="small" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="(suggestion, index) in suggestions"
|
v-for="(suggestion, index) in suggestions"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="suggestion-item"
|
class="suggestion-item"
|
||||||
:class="{ 'highlighted': index === highlightedIndex }"
|
:class="{ highlighted: index === highlightedIndex }"
|
||||||
@mousedown.prevent="selectSuggestion(suggestion)"
|
@mousedown.prevent="selectSuggestion(suggestion)"
|
||||||
@mouseenter="highlightedIndex = index"
|
@mouseenter="highlightedIndex = index"
|
||||||
>
|
>
|
||||||
<i class="ri-search-line suggestion-icon"></i>
|
<i class="ri-search-line suggestion-icon"></i>
|
||||||
<span>{{ suggestion }}</span>
|
<span>{{ suggestion }}</span>
|
||||||
@@ -162,10 +164,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { useDebounceFn } from '@vueuse/core';
|
||||||
import { computed, onMounted, ref, watch, watchEffect } from 'vue';
|
import { computed, onMounted, ref, watch, watchEffect } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useDebounceFn } from '@vueuse/core';
|
|
||||||
|
|
||||||
import { getSearchKeyword } from '@/api/home';
|
import { getSearchKeyword } from '@/api/home';
|
||||||
import { getUserDetail } from '@/api/login';
|
import { getUserDetail } from '@/api/login';
|
||||||
@@ -427,7 +429,8 @@ const handleKeydown = (event: KeyboardEvent) => {
|
|||||||
break;
|
break;
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
event.preventDefault(); // 阻止光标移动到开头
|
event.preventDefault(); // 阻止光标移动到开头
|
||||||
highlightedIndex.value = (highlightedIndex.value - 1 + suggestions.value.length) % suggestions.value.length;
|
highlightedIndex.value =
|
||||||
|
(highlightedIndex.value - 1 + suggestions.value.length) % suggestions.value.length;
|
||||||
break;
|
break;
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
event.preventDefault(); // 阻止表单默认提交行为
|
event.preventDefault(); // 阻止表单默认提交行为
|
||||||
|
|||||||
Reference in New Issue
Block a user