feat(download): 新增历史版本选择,重构下载全链路逻辑与UI

- 重构lib/github-releases.ts:统一预览版判断逻辑,新增支持`vX.Y.Z-N.beta`格式的beta标签,提取复用函数简化代码,将原有重复工具方法抽取至此统一管理并新增平台资产匹配工具
- 新增通用PlatformDownloadGrid多平台下载卡片组件,标准化多平台下载UI实现
- 重构两个下载API接口:统一返回格式并新增历史版本列表数据
- 重构/download和/launcher/join-beta页面:替换使用新的下载组件,新增历史版本选择功能
This commit is contained in:
2026-09-05 19:52:54 +08:00
parent 67b9d26460
commit 5997b1c7ea
7 changed files with 588 additions and 342 deletions
+24 -9
View File
@@ -20,8 +20,28 @@ const GH_HEADERS: Record<string, string> = {
"X-GitHub-Api-Version": "2022-11-28",
};
/** 预览版 tag 形态:v1.2.5-beta.16 */
export const BETA_TAG = /^v?\d+\.\d+\.\d+-beta\.\d+$/i;
/**
* 预览版 tag 形态(兼容两代方案):
* v1.2.5-beta.16 (旧,-beta.N 尾号)
* v1.2.6-29.beta(新,-N.beta 尾号)
*/
export const BETA_TAG =
/^v?\d+\.\d+\.\d+(-beta\.\d+|-\d+\.beta)$/i;
/** 判断 tag 是否为预览版(不要求整串匹配,供 history 等筛选使用) */
export function isBetaTag(tag: string) {
return /(-beta\.\d+|-\d+\.beta)$/i.test(String(tag || ""));
}
/** 判断 release 是否为预览版:优先 prerelease 标记,其次按 tag 形态 */
export function isBetaRelease(release: any) {
return !!(
release &&
!release.draft &&
(release.prerelease === true ||
isBetaTag(String(release.tag_name || "")))
);
}
interface FetchResult {
ok: boolean;
@@ -80,14 +100,9 @@ function byPublishedDesc(a: any, b: any) {
return tb.localeCompare(ta);
}
/** 最新预览版 releaseprerelease 标记或 -beta.N tag */
/** 最新预览版 releaseprerelease 标记或预览 tag */
export function pickBetaRelease(releases: any[]) {
const betas = (releases || []).filter(
(r) =>
r &&
!r.draft &&
(r.prerelease === true || BETA_TAG.test(String(r.tag_name || "")))
);
const betas = (releases || []).filter((r) => isBetaRelease(r));
betas.sort(byPublishedDesc);
return betas[0] || null;
}