|
| 1 | +// @ai-context |
| 2 | +// 下载 CTA 卡片:从自建服务器 latest.json 动态获取版本信息与安装包直链(国内主源), |
| 3 | +// 拉取失败时静默回退 GitHub Releases。Download CTA: server-hosted direct link with GitHub fallback. |
| 4 | +// Why: 国内访问 GitHub Release 不稳定,服务器直链提升首下载转化;版本信息动态化消灭硬编码。 |
| 5 | +"use client"; |
| 6 | + |
| 7 | +import { useEffect, useState } from "react"; |
| 8 | + |
| 9 | +/** 自建服务器下载源(release.yml CI 发版时同步安装包与 latest.json) */ |
| 10 | +const DOWNLOAD_BASE = "https://entropydecrease.com/downloads"; |
| 11 | +/** GitHub Releases 备用源 */ |
| 12 | +const GITHUB_RELEASES = "https://github.com/Aparencia/Entropydecrease/releases/latest"; |
| 13 | + |
| 14 | +/** 兜底展示信息(latest.json 不可达时使用) */ |
| 15 | +const FALLBACK = { version: "0.15.0", date: "2026-07", sizeMB: 120 }; |
| 16 | + |
| 17 | +/** release.yml 生成的 latest.json 结构 */ |
| 18 | +interface LatestInfo { |
| 19 | + version: string; |
| 20 | + fileName: string; |
| 21 | + size: number; |
| 22 | + releaseDate: string; |
| 23 | +} |
| 24 | + |
| 25 | +const SYSTEM_REQ = [ |
| 26 | + { label: "操作系统", value: "Windows 10 / 11 (64位)" }, |
| 27 | + { label: "处理器", value: "Intel i5 / AMD Ryzen 5 或更高" }, |
| 28 | + { label: "内存", value: "8 GB RAM 以上" }, |
| 29 | + { label: "存储空间", value: "500 MB 可用空间" }, |
| 30 | +]; |
| 31 | + |
| 32 | +export function DownloadCta() { |
| 33 | + const [latest, setLatest] = useState<LatestInfo | null>(null); |
| 34 | + |
| 35 | + useEffect(() => { |
| 36 | + const controller = new AbortController(); |
| 37 | + fetch(`${DOWNLOAD_BASE}/latest.json`, { signal: controller.signal, cache: "no-store" }) |
| 38 | + .then((res) => (res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`)))) |
| 39 | + .then((data: LatestInfo) => { |
| 40 | + if (data?.version && data?.fileName) setLatest(data); |
| 41 | + }) |
| 42 | + .catch(() => { |
| 43 | + /* 服务器源不可达:保持 GitHub 回退,不打扰用户 */ |
| 44 | + }); |
| 45 | + return () => controller.abort(); |
| 46 | + }, []); |
| 47 | + |
| 48 | + // 服务器直链优先;元数据未就绪时回退 GitHub Release 页 |
| 49 | + const downloadUrl = latest |
| 50 | + ? `${DOWNLOAD_BASE}/${encodeURIComponent(latest.fileName)}` |
| 51 | + : GITHUB_RELEASES; |
| 52 | + const version = latest?.version ?? FALLBACK.version; |
| 53 | + const date = latest?.releaseDate ?? FALLBACK.date; |
| 54 | + const sizeMB = latest ? Math.round(latest.size / 1024 / 1024) : FALLBACK.sizeMB; |
| 55 | + |
| 56 | + return ( |
| 57 | + <div |
| 58 | + className="rounded-3xl p-10 text-center" |
| 59 | + style={{ |
| 60 | + background: "var(--kb-bg-elevated)", |
| 61 | + border: "1px solid var(--kb-glass-border)", |
| 62 | + boxShadow: "var(--kb-shadow-brand)", |
| 63 | + }} |
| 64 | + > |
| 65 | + <div className="flex items-center justify-center gap-3 mb-6"> |
| 66 | + <span |
| 67 | + className="w-12 h-12 rounded-2xl flex items-center justify-center text-lg font-bold text-white" |
| 68 | + style={{ background: "linear-gradient(135deg, var(--kb-brand-400), var(--kb-accent-500))" }} |
| 69 | + > |
| 70 | + 熵 |
| 71 | + </span> |
| 72 | + <div className="text-left"> |
| 73 | + <h2 className="font-serif text-xl font-bold text-kb-text">熵减 Entropydecrease</h2> |
| 74 | + <p className="text-xs text-kb-text3">v{version} 正式版 · {date}</p> |
| 75 | + </div> |
| 76 | + </div> |
| 77 | + |
| 78 | + <a |
| 79 | + href={downloadUrl} |
| 80 | + {...(latest ? {} : { target: "_blank", rel: "noopener noreferrer" })} |
| 81 | + className="inline-block px-12 py-4 rounded-2xl text-white font-medium text-lg transition-all duration-500 hover:scale-[1.04] active:scale-[0.97] mb-4" |
| 82 | + style={{ |
| 83 | + background: "linear-gradient(135deg, var(--kb-amber), var(--kb-accent-400))", |
| 84 | + boxShadow: "var(--kb-shadow-accent)", |
| 85 | + }} |
| 86 | + > |
| 87 | + ⬇ 下载 Windows 版 |
| 88 | + </a> |
| 89 | + |
| 90 | + <p className="text-xs text-kb-text3 mb-2"> |
| 91 | + 约 {sizeMB} MB · 适用于 Windows 10/11 (64位) · 免费开源 |
| 92 | + </p> |
| 93 | + <p className="text-xs mb-8"> |
| 94 | + <a |
| 95 | + href={GITHUB_RELEASES} |
| 96 | + target="_blank" |
| 97 | + rel="noopener noreferrer" |
| 98 | + className="text-kb-text3 underline underline-offset-2 transition-colors duration-300 hover:text-kb-text2" |
| 99 | + > |
| 100 | + 下载缓慢?使用 GitHub 备用源 ↗ |
| 101 | + </a> |
| 102 | + </p> |
| 103 | + |
| 104 | + {/* 系统要求 */} |
| 105 | + <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 text-left"> |
| 106 | + {SYSTEM_REQ.map((req) => ( |
| 107 | + <div key={req.label} className="rounded-xl p-3.5" style={{ background: "var(--kb-bg-tertiary)" }}> |
| 108 | + <p className="text-[10px] text-kb-text3 uppercase tracking-wider mb-1">{req.label}</p> |
| 109 | + <p className="text-xs text-kb-text2 leading-snug">{req.value}</p> |
| 110 | + </div> |
| 111 | + ))} |
| 112 | + </div> |
| 113 | + </div> |
| 114 | + ); |
| 115 | +} |
0 commit comments