feat(server+web): 客户端下载闭环——pangolin-server /downloads + 官网下载链接
Deploy Server / deploy-server (push) Successful in 2m59s
Deploy Server / deploy-server (push) Successful in 2m59s
- server: /downloads/* 公开静态服务(NewDownloadsHandler,DOWNLOADS_DIR 默认
/var/lib/pangolin/downloads),防目录穿越/不列目录/缺目录不崩,Cache-Control:
no-cache 保证 CI 覆盖后永远最新。挂在 /healthz 同级(免鉴权)。含 4 项测试。
- deploy.sh: install -d 下载目录 + server.env 注入 DOWNLOADS_DIR。
- web: site.ts 增 downloads.{android,windows}(→ https://api.yanmeiai.com/downloads/*);
Download.astro 接上 Android/Windows 按钮,iOS/macOS/Linux 改「即将推出」禁用态。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
---
|
||||
import Icon from './Icon.astro';
|
||||
import type { T } from '../i18n/strings';
|
||||
import { SITE } from '../config/site';
|
||||
|
||||
interface Props { t: T }
|
||||
const { t } = Astro.props;
|
||||
|
||||
const plats = [
|
||||
// href 缺省 = 本轮未接入下载(iOS / macOS / Linux),按钮渲染为禁用态占位。
|
||||
const plats: { icon: string; name: string; ver: string; href?: string }[] = [
|
||||
{ icon: 'smartphone', name: 'iOS', ver: 'iOS 16+' },
|
||||
{ icon: 'smartphone', name: 'Android', ver: 'Android 9+' },
|
||||
{ icon: 'smartphone', name: 'Android', ver: 'Android 9+', href: SITE.downloads.android },
|
||||
{ icon: 'laptop', name: 'macOS', ver: 'macOS 12+' },
|
||||
{ icon: 'monitor', name: 'Windows', ver: 'Win 10/11' },
|
||||
{ icon: 'monitor', name: 'Windows', ver: 'Win 10/11', href: SITE.downloads.windows },
|
||||
{ icon: 'terminal', name: 'Linux', ver: 'deb / rpm' },
|
||||
];
|
||||
---
|
||||
@@ -26,7 +28,11 @@ const plats = [
|
||||
<div class="ico"><Icon name={p.icon} /></div>
|
||||
<div class="pn">{p.name}</div>
|
||||
<div class="pv">{p.ver}</div>
|
||||
<a class="gb"><Icon name="download" /><span>{t('dl.get')}</span></a>
|
||||
{p.href ? (
|
||||
<a class="gb" href={p.href}><Icon name="download" /><span>{t('dl.get')}</span></a>
|
||||
) : (
|
||||
<span class="gb disabled" aria-disabled="true"><Icon name="download" /><span>{t('dl.soon')}</span></span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -19,4 +19,15 @@ export const SITE = {
|
||||
|
||||
/** 自助发卡商店 —— 占位待定(#24)。 */
|
||||
store: { label: 'shop.pangolin.vpn' },
|
||||
|
||||
/**
|
||||
* 客户端安装包直链。控制面 pangolin-server 通过 Cloudflare Tunnel 对外暴露
|
||||
* /downloads/<file>(origin = 127.0.0.1:8080),文件由
|
||||
* scripts/ci/deploy-client.sh 每次构建 scp 覆盖到 pangolin1:/var/lib/pangolin/downloads/,
|
||||
* 每平台固定文件名、只保留最新一份。iOS / macOS / Linux 本轮未接入下载按钮。
|
||||
*/
|
||||
downloads: {
|
||||
android: 'https://api.yanmeiai.com/downloads/pangolin-android.apk',
|
||||
windows: 'https://api.yanmeiai.com/downloads/pangolin-windows-x64-setup.exe',
|
||||
},
|
||||
} as const;
|
||||
|
||||
@@ -128,6 +128,7 @@ export const STRINGS: Record<string, [string, string]> = {
|
||||
'dl.h': ['全平台,随处可用', 'Every platform, everywhere'],
|
||||
'dl.sub': ['一个账户,所有设备同步。下载即用,无需配置。', 'One account syncs every device. Download and go.'],
|
||||
'dl.get': ['下载', 'Download'],
|
||||
'dl.soon': ['敬请期待', 'Coming soon'],
|
||||
|
||||
'docs.eyebrow': ['文档', 'Docs'],
|
||||
'docs.h': ['需要帮助?都在这里', 'Need help? It’s all here'],
|
||||
|
||||
@@ -189,6 +189,8 @@ section{padding:88px 0}
|
||||
.dl .pv{font-size:12px;color:var(--fg3);margin:3px 0 14px;font-family:var(--font-mono)}
|
||||
.dl .gb{display:inline-flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:var(--accent)}
|
||||
.dl .gb svg{width:14px;height:14px}
|
||||
.dl .gb.disabled{color:var(--fg3);cursor:not-allowed;pointer-events:none}
|
||||
.dl .gb.disabled svg{opacity:.5}
|
||||
|
||||
/* ---------- docs ---------- */
|
||||
.docs-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-top:44px}
|
||||
|
||||
Reference in New Issue
Block a user