mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-05-01 05:27:22 +08:00
✨ feat: 增加动态代理节点获取和缓存机制
This commit is contained in:
@@ -72,7 +72,7 @@ import { marked } from 'marked';
|
|||||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||||
import { useStore } from 'vuex';
|
import { useStore } from 'vuex';
|
||||||
|
|
||||||
import { checkUpdate, UpdateResult } from '@/utils/update';
|
import { checkUpdate, getProxyNodes, UpdateResult } from '@/utils/update';
|
||||||
|
|
||||||
import config from '../../../../package.json';
|
import config from '../../../../package.json';
|
||||||
|
|
||||||
@@ -226,7 +226,13 @@ const handleUpdate = async () => {
|
|||||||
try {
|
try {
|
||||||
downloading.value = true;
|
downloading.value = true;
|
||||||
downloadStatus.value = '准备下载...';
|
downloadStatus.value = '准备下载...';
|
||||||
window.electron.ipcRenderer.send('start-download', downloadUrl);
|
|
||||||
|
// 获取代理节点列表
|
||||||
|
const proxyHosts = await getProxyNodes();
|
||||||
|
const proxyDownloadUrl = `${proxyHosts[0]}/${downloadUrl}`;
|
||||||
|
|
||||||
|
// 发送所有可能的下载地址到主进程
|
||||||
|
window.electron.ipcRenderer.send('start-download', proxyDownloadUrl);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
downloading.value = false;
|
downloading.value = false;
|
||||||
window.$message.error('启动下载失败,请重试或手动下载');
|
window.$message.error('启动下载失败,请重试或手动下载');
|
||||||
|
|||||||
+102
-12
@@ -15,6 +15,23 @@ interface GithubReleaseInfo {
|
|||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ProxyNode {
|
||||||
|
url: string;
|
||||||
|
server: string;
|
||||||
|
ip: string;
|
||||||
|
location: string;
|
||||||
|
latency: number;
|
||||||
|
speed: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ProxyResponse {
|
||||||
|
code: number;
|
||||||
|
msg: string;
|
||||||
|
data: ProxyNode[];
|
||||||
|
total: number;
|
||||||
|
update_time: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UpdateResult {
|
export interface UpdateResult {
|
||||||
hasUpdate: boolean;
|
hasUpdate: boolean;
|
||||||
latestVersion: string;
|
latestVersion: string;
|
||||||
@@ -30,6 +47,81 @@ export interface UpdateResult {
|
|||||||
} | null;
|
} | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 缓存相关配置
|
||||||
|
const CACHE_KEY = 'github_proxy_nodes';
|
||||||
|
const CACHE_EXPIRE_TIME = 1000 * 60 * 10; // 10分钟过期
|
||||||
|
|
||||||
|
// 请求配置
|
||||||
|
const REQUEST_TIMEOUT = 2000; // 2秒超时
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从缓存获取代理节点
|
||||||
|
*/
|
||||||
|
const getCachedProxyNodes = (): { nodes: string[]; timestamp: number } | null => {
|
||||||
|
const cached = localStorage.getItem(CACHE_KEY);
|
||||||
|
if (cached) {
|
||||||
|
const { nodes, timestamp } = JSON.parse(cached);
|
||||||
|
if (Date.now() - timestamp < CACHE_EXPIRE_TIME) {
|
||||||
|
return { nodes, timestamp };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存代理节点
|
||||||
|
*/
|
||||||
|
const cacheProxyNodes = (nodes: string[]) => {
|
||||||
|
localStorage.setItem(
|
||||||
|
CACHE_KEY,
|
||||||
|
JSON.stringify({
|
||||||
|
nodes,
|
||||||
|
timestamp: Date.now()
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取代理节点列表
|
||||||
|
*/
|
||||||
|
export const getProxyNodes = async (): Promise<string[]> => {
|
||||||
|
// 尝试从缓存获取
|
||||||
|
const cached = getCachedProxyNodes();
|
||||||
|
if (cached) {
|
||||||
|
return cached.nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 获取最新代理节点
|
||||||
|
const { data } = await axios.get<ProxyResponse>('https://api.akams.cn/github', {
|
||||||
|
timeout: REQUEST_TIMEOUT
|
||||||
|
});
|
||||||
|
if (data.code === 200) {
|
||||||
|
// 按速度排序并获取前10个节点
|
||||||
|
const nodes = data.data
|
||||||
|
.sort((a, b) => b.speed - a.speed)
|
||||||
|
.slice(0, 10)
|
||||||
|
.map((node) => node.url);
|
||||||
|
|
||||||
|
// 缓存节点
|
||||||
|
cacheProxyNodes(nodes);
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取代理节点失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用备用节点
|
||||||
|
return [
|
||||||
|
'https://gh.lk.cc',
|
||||||
|
'https://ghproxy.cn',
|
||||||
|
'https://ghproxy.net',
|
||||||
|
'https://gitproxy.click',
|
||||||
|
'https://github.tbedu.top',
|
||||||
|
'https://github.moeyy.xyz'
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 GitHub 最新发布版本信息
|
* 获取 GitHub 最新发布版本信息
|
||||||
*/
|
*/
|
||||||
@@ -38,22 +130,15 @@ export const getLatestReleaseInfo = async (): Promise<GithubReleaseInfo | null>
|
|||||||
const token = import.meta.env.VITE_GITHUB_TOKEN;
|
const token = import.meta.env.VITE_GITHUB_TOKEN;
|
||||||
const headers = {};
|
const headers = {};
|
||||||
|
|
||||||
// GitHub API 代理地址列表
|
// 获取代理节点列表
|
||||||
const proxyHosts = [
|
const proxyHosts = await getProxyNodes();
|
||||||
'https://gh.lk.cc',
|
|
||||||
'https://ghproxy.cn',
|
|
||||||
'https://ghproxy.net',
|
|
||||||
'https://gitproxy.click',
|
|
||||||
'https://github.tbedu.top',
|
|
||||||
'https://github.moeyy.xyz'
|
|
||||||
];
|
|
||||||
|
|
||||||
// 构建 API URL 列表
|
// 构建 API URL 列表
|
||||||
const apiUrls = [
|
const apiUrls = [
|
||||||
// 原始地址
|
// 原始地址
|
||||||
'https://api.github.com/repos/algerkong/AlgerMusicPlayer/releases/latest',
|
'https://api.github.com/repos/algerkong/AlgerMusicPlayer/releases/latest',
|
||||||
|
|
||||||
// 使用各种代理
|
// 使用代理节点
|
||||||
...proxyHosts.map(
|
...proxyHosts.map(
|
||||||
(host) =>
|
(host) =>
|
||||||
`${host}/https://raw.githubusercontent.com/algerkong/AlgerMusicPlayer/dev_electron/package.json`
|
`${host}/https://raw.githubusercontent.com/algerkong/AlgerMusicPlayer/dev_electron/package.json`
|
||||||
@@ -66,12 +151,17 @@ export const getLatestReleaseInfo = async (): Promise<GithubReleaseInfo | null>
|
|||||||
|
|
||||||
for (const url of apiUrls) {
|
for (const url of apiUrls) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(url, { headers });
|
const response = await axios.get(url, {
|
||||||
|
headers,
|
||||||
|
timeout: REQUEST_TIMEOUT
|
||||||
|
});
|
||||||
|
|
||||||
if (url.includes('package.json')) {
|
if (url.includes('package.json')) {
|
||||||
// 如果是 package.json,获取对应的 CHANGELOG
|
// 如果是 package.json,获取对应的 CHANGELOG
|
||||||
const changelogUrl = url.replace('package.json', 'CHANGELOG.md');
|
const changelogUrl = url.replace('package.json', 'CHANGELOG.md');
|
||||||
const changelogResponse = await axios.get(changelogUrl);
|
const changelogResponse = await axios.get(changelogUrl, {
|
||||||
|
timeout: REQUEST_TIMEOUT
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tag_name: response.data.version,
|
tag_name: response.data.version,
|
||||||
|
|||||||
Reference in New Issue
Block a user