Files
jiu/web/download.njk
T
wangjia d94c6b109b
Deploy / build-windows (push) Failing after 19s
Deploy / build-linux-web (push) Successful in 51s
Deploy / build-macos (push) Failing after 32s
Deploy / release-deploy (push) Has been skipped
chore: release v1.0.4
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 23:53:51 +08:00

521 lines
20 KiB
Plaintext

---
layout: base.njk
title: 下载
description: 下载岩美酒库管理系统,Web 版现已上线,Windows / macOS / iOS / Android 客户端即将推出。
pageStyle: |
/* ── Page header ── */
.page-header {
padding: 72px 0 56px;
background:
radial-gradient(700px 360px at 80% 20%, rgba(37, 99, 172, 0.06), transparent 60%),
linear-gradient(180deg, #FBFCFD 0%, #FFFFFF 80%);
border-bottom: 1px solid var(--border-subtle);
}
.ph-inner {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
.ph-eyebrow {
font-size: var(--text-xs); font-weight: 600;
letter-spacing: 0.12em; color: var(--brand-500);
text-transform: uppercase;
margin: 0 0 12px;
display: flex; align-items: center; gap: 8px;
}
.ph-eyebrow .version-badge {
background: var(--brand-500); color: #fff;
padding: 3px 8px; border-radius: var(--radius-sm);
font-family: var(--font-mono);
letter-spacing: 0.02em; font-size: 11px;
}
.ph-title {
font-size: 44px; font-weight: 700; line-height: 1.15;
letter-spacing: var(--tracking-cn-display);
color: var(--brand-900); margin: 0 0 18px;
}
.ph-lead {
font-size: var(--text-lg); color: var(--gray-600);
line-height: 1.6; margin: 0 0 24px; max-width: 480px;
}
.ph-meta {
display: flex; gap: 24px;
font-size: var(--text-sm); color: var(--fg-muted);
border-top: 1px solid var(--border-subtle);
padding-top: 16px;
}
.ph-meta-item { display: flex; flex-direction: column; gap: 2px; }
.ph-meta-label { font-size: 11px; color: var(--fg-subtle); letter-spacing: 0.04em; }
.ph-meta-val { font-size: var(--text-sm); color: var(--gray-800); font-weight: 500; }
/* ── Auto-detect card ── */
.detect-card {
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
overflow: hidden;
}
.detect-card-head {
padding: 14px 20px;
background: var(--gray-50);
border-bottom: 1px solid var(--border-subtle);
font-size: var(--text-xs); color: var(--fg-muted);
display: flex; justify-content: space-between; align-items: center;
}
.detect-card-head .head-left { display: flex; align-items: center; gap: 6px; }
.detect-card-head .head-left svg { width: 14px; height: 14px; color: var(--success-500); }
.detect-card-body {
padding: 28px;
display: flex; gap: 24px; align-items: center;
}
.detect-icon {
width: 72px; height: 72px;
background: var(--brand-50); border-radius: 16px;
display: grid; place-items: center;
color: var(--brand-500); flex-shrink: 0;
}
.detect-icon svg { width: 38px; height: 38px; }
.detect-info { flex: 1; }
.detect-info h3 { margin: 0 0 4px; font-size: var(--text-xl); font-weight: 600; color: var(--brand-900); }
.detect-info p { margin: 0; font-size: var(--text-sm); color: var(--fg-muted); }
.detect-card-actions { padding: 0 28px 28px; display: flex; gap: 8px; }
.detect-card-actions .btn-primary { flex: 1; justify-content: center; }
/* ── Platform grid ── */
.dl-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
margin-top: 32px;
}
.dl-card {
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
padding: 20px;
display: flex; flex-direction: column;
transition: border-color var(--duration-base) var(--ease-standard),
box-shadow var(--duration-base) var(--ease-standard);
}
.dl-card:hover { border-color: var(--brand-300); box-shadow: var(--shadow-sm); }
.dl-card.detected { border-color: var(--brand-400); box-shadow: var(--shadow-md); }
.dl-card.coming-soon { opacity: 0.65; }
.dl-card-icon {
width: 48px; height: 48px;
background: var(--brand-50); border-radius: var(--radius-md);
display: grid; place-items: center; color: var(--brand-500);
margin-bottom: 12px;
}
.dl-card-icon svg { width: 24px; height: 24px; }
.dl-card-name { font-size: var(--text-md); font-weight: 600; color: var(--brand-900); margin: 0 0 4px; }
.dl-card-desc { font-size: var(--text-xs); color: var(--fg-muted); margin: 0 0 14px; line-height: 1.5; flex: 1; }
.dl-status {
display: inline-flex; align-items: center; gap: 4px;
font-size: 10px; font-weight: 600; letter-spacing: 0.04em;
padding: 3px 8px; border-radius: var(--radius-pill); margin-bottom: 12px;
}
.dl-status.available { background: var(--success-50); color: var(--success-700); }
.dl-status.soon { background: var(--gray-100); color: var(--fg-muted); }
.dl-card-btn {
display: flex; align-items: center; justify-content: center; gap: 6px;
height: 34px; padding: 0 14px;
border-radius: var(--radius-md);
font-size: var(--text-sm); font-weight: 500;
border: 1px solid transparent;
cursor: pointer; width: 100%;
transition: background var(--duration-fast) var(--ease-standard);
text-decoration: none;
}
.dl-card-btn.primary { background: var(--brand-500); color: #fff; }
.dl-card-btn.primary:hover { background: var(--brand-600); }
.dl-card-btn.disabled {
background: var(--gray-100); color: var(--fg-muted);
cursor: default; pointer-events: none;
border-color: var(--border-subtle);
}
.dl-card-btn svg { width: 14px; height: 14px; }
/* ── System requirements (rendered markdown) ── */
.sysreq-content h2 {
font-size: var(--text-xl); font-weight: 600;
color: var(--brand-900); margin: 28px 0 12px;
letter-spacing: var(--tracking-cn-display);
padding-bottom: 8px;
border-bottom: 1px solid var(--border-subtle);
}
.sysreq-content h2:first-child { margin-top: 0; }
.sysreq-content table {
width: 100%; border-collapse: collapse;
font-size: var(--text-sm); color: var(--gray-800);
margin-bottom: 8px;
}
.sysreq-content th {
text-align: left; font-size: 11px; font-weight: 600;
letter-spacing: 0.04em; text-transform: uppercase;
color: var(--fg-muted); padding: 8px 12px;
background: var(--gray-50);
border: 1px solid var(--border-subtle);
}
.sysreq-content td {
padding: 10px 12px;
border: 1px solid var(--border-subtle);
vertical-align: top;
}
.sysreq-content tr:hover td { background: var(--gray-25); }
.sysreq-content p { font-size: var(--text-sm); color: var(--fg-muted); margin: 8px 0 0; }
/* ── Changelog timeline ── */
.changelog {
display: grid;
grid-template-columns: 180px 1fr;
gap: 0;
margin-top: 40px;
border-left: 1px solid var(--border-subtle);
}
.changelog-entry { display: contents; }
.changelog-meta {
padding: 28px 24px 28px 32px;
position: relative;
border-bottom: 1px solid var(--border-subtle);
}
.changelog-meta::before {
content: '';
position: absolute; left: -7px; top: 36px;
width: 13px; height: 13px; border-radius: 50%;
background: var(--gray-0); border: 3px solid var(--gray-300);
}
.changelog-entry.current .changelog-meta::before {
background: var(--brand-500); border-color: var(--brand-100);
box-shadow: 0 0 0 4px var(--brand-50);
}
.changelog-version {
font-family: var(--font-mono); font-size: var(--text-md); font-weight: 600;
color: var(--brand-900); margin-bottom: 4px;
}
.changelog-date { font-size: var(--text-xs); color: var(--fg-muted); }
.changelog-tag {
display: inline-block; font-size: 10px;
background: var(--success-50); color: var(--success-700);
padding: 2px 8px; border-radius: var(--radius-pill);
font-weight: 500; margin-top: 8px;
}
.changelog-body {
padding: 28px 0 28px 32px;
border-bottom: 1px solid var(--border-subtle);
border-left: 1px solid var(--border-subtle);
margin-left: -1px;
}
.changelog-entry:last-child .changelog-meta,
.changelog-entry:last-child .changelog-body { border-bottom: none; }
.changelog-intro {
font-size: var(--text-sm); color: var(--gray-700);
line-height: 1.6; margin: 0 0 16px;
}
.changelog-cat { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.changelog-cat-label {
font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
color: var(--fg-muted); text-transform: uppercase;
display: flex; align-items: center; gap: 6px; margin-bottom: 2px;
}
.changelog-cat-label .dot { width: 6px; height: 6px; border-radius: 50%; }
.dot-feature { background: var(--brand-500); }
.dot-improve { background: var(--success-500); }
.dot-fix { background: var(--warning-500); }
.changelog-cat ul {
margin: 0; padding: 0; list-style: none;
font-size: var(--text-sm); color: var(--gray-700); line-height: 1.6;
}
.changelog-cat ul li {
padding: 3px 0 3px 16px; position: relative;
}
.changelog-cat ul li::before {
content: ''; position: absolute; left: 0; top: 11px;
width: 6px; height: 1px; background: var(--gray-400);
}
/* ── Responsive ── */
@media (max-width: 1024px) {
.ph-inner { grid-template-columns: 1fr; gap: 32px; }
.ph-title { font-size: 36px; }
.dl-grid { grid-template-columns: repeat(3, 1fr); }
.changelog { grid-template-columns: 120px 1fr; }
}
@media (max-width: 768px) {
.dl-grid { grid-template-columns: repeat(2, 1fr); }
.page-header { padding: 48px 0 40px; }
}
---
<!-- ============================== PAGE HEADER ============================== -->
<section class="page-header">
<div class="container ph-inner">
<div>
<div class="ph-eyebrow">
<span class="version-badge">v{{ changelog[0].version }}</span>
<span>下载岩美</span>
</div>
<h1 class="ph-title">随时随地,<br/>轻松管理酒库。</h1>
<p class="ph-lead">
Web 版与 Windows 桌面版已正式上线,macOS、iOS、Android 客户端即将推出。
</p>
<div class="ph-meta">
<div class="ph-meta-item">
<div class="ph-meta-label">最新版本</div>
<div class="ph-meta-val version-badge">v{{ changelog[0].version }}</div>
</div>
<div class="ph-meta-item">
<div class="ph-meta-label">发布日期</div>
<div class="ph-meta-val">{{ changelog[0].date }}</div>
</div>
<div class="ph-meta-item">
<div class="ph-meta-label">可用平台</div>
<div class="ph-meta-val">Web / Windows</div>
</div>
</div>
</div>
<!-- Auto-detect card -->
<div class="detect-card">
<div class="detect-card-head">
<span class="head-left">
<i data-lucide="zap" class="icon"></i>
已自动识别您的环境
</span>
<span style="font-family: var(--font-mono); color: var(--fg-subtle);">推荐</span>
</div>
<div class="detect-card-body">
<div class="detect-icon" id="detect-icon">
<i data-lucide="globe" class="icon"></i>
</div>
<div class="detect-info">
<h3 id="detect-name">Web 版</h3>
<p id="detect-desc">浏览器直接访问,功能完整,无需下载安装。</p>
</div>
</div>
<div class="detect-card-actions">
<a href="https://jiu.51yanmei.com/app/" class="btn btn-primary btn-lg" id="detect-btn">
<i data-lucide="arrow-right" class="icon"></i>
立即使用 Web 版
</a>
</div>
</div>
</div>
</section>
<!-- ============================== PLATFORM GRID ============================== -->
<section class="section">
<div class="container">
<h2 class="fs-3xl fw-6 text-brand-900 m-0 mb-6" style="letter-spacing: var(--tracking-cn-display);">支持的平台</h2>
<p class="fs-md text-muted m-0 mb-8">Web 版与 Windows 桌面版现已可用,其余平台正在开发中。</p>
<div class="dl-grid" id="platform-grid">
<!-- Web -->
<div class="dl-card" data-platform="web">
<div class="dl-card-icon"><i data-lucide="globe" class="icon"></i></div>
<h3 class="dl-card-name">Web 版</h3>
<p class="dl-card-desc">浏览器直接访问,功能完整,无需安装,支持 PC 与平板。</p>
<span class="dl-status available">✓ 已上线</span>
<a href="https://jiu.51yanmei.com/app/" class="dl-card-btn primary">
<i data-lucide="arrow-right" class="icon"></i>立即使用
</a>
</div>
<!-- Windows -->
<div class="dl-card" data-platform="windows">
<div class="dl-card-icon"><i data-lucide="monitor" class="icon"></i></div>
<h3 class="dl-card-name">Windows</h3>
<p class="dl-card-desc">原生桌面客户端,支持 Win 10/11(64 位),离线模式与本地打印。</p>
<span class="dl-status available">✓ 已支持</span>
<a href="#" class="dl-card-btn primary" id="windows-dl-btn">
<i data-lucide="download" class="icon"></i>下载 Windows 版
</a>
</div>
<!-- macOS -->
<div class="dl-card" data-platform="macos">
<div class="dl-card-icon"><i data-lucide="laptop" class="icon"></i></div>
<h3 class="dl-card-name">macOS</h3>
<p class="dl-card-desc">支持 Apple Silicon 与 Intel,解压即用,首次运行右键→打开。</p>
<span class="dl-status available">✓ 已支持</span>
<a href="#" class="dl-card-btn primary" id="macos-dl-btn">
<i data-lucide="download" class="icon"></i>下载 macOS 版
</a>
</div>
<!-- iOS -->
<div class="dl-card coming-soon" data-platform="ios">
<div class="dl-card-icon"><i data-lucide="smartphone" class="icon"></i></div>
<h3 class="dl-card-name">iOS</h3>
<p class="dl-card-desc">iPhone 与 iPad 通用,支持扫码与推送通知。</p>
<span class="dl-status soon">敬请期待</span>
<span class="dl-card-btn disabled">
<i data-lucide="clock" class="icon"></i>即将推出
</span>
</div>
<!-- Android -->
<div class="dl-card coming-soon" data-platform="android">
<div class="dl-card-icon"><i data-lucide="tablet-smartphone" class="icon"></i></div>
<h3 class="dl-card-name">Android</h3>
<p class="dl-card-desc">手机与平板通用,支持主流应用商店及 APK 安装。</p>
<span class="dl-status soon">敬请期待</span>
<span class="dl-card-btn disabled">
<i data-lucide="clock" class="icon"></i>即将推出
</span>
</div>
</div>
</div>
</section>
<!-- ============================== SYSTEM REQUIREMENTS ============================== -->
<section class="section bg-25">
<div class="container">
<h2 class="fs-3xl fw-6 text-brand-900 m-0 mb-6" style="letter-spacing: var(--tracking-cn-display);">系统要求</h2>
<p class="fs-md text-muted m-0 mb-32">在以下环境中均经过测试与验证。</p>
<div class="card p-32 sysreq-content">
{{ sysreq | safe }}
</div>
</div>
</section>
<!-- ============================== CHANGELOG ============================== -->
<section class="section">
<div class="container">
<h2 class="fs-3xl fw-6 text-brand-900 m-0 mb-6" style="letter-spacing: var(--tracking-cn-display);">版本更新日志</h2>
<p class="fs-md text-muted m-0">最近 {{ changelog | length }} 个版本。</p>
<div class="changelog">
{% for entry in changelog %}
<div class="changelog-entry{% if loop.first %} current{% endif %}">
<div class="changelog-meta">
<div class="changelog-version">v{{ entry.version }}</div>
<div class="changelog-date">{{ entry.date }}</div>
{% if loop.first %}<span class="changelog-tag">当前版本</span>{% endif %}
</div>
<div class="changelog-body">
{% if entry.intro %}
<p class="changelog-intro">{{ entry.intro }}</p>
{% endif %}
{% for section in entry.sections %}
<div class="changelog-cat">
<div class="changelog-cat-label">
{% if section.type == "新功能" %}
<span class="dot dot-feature"></span>新功能
{% elif section.type == "改进" %}
<span class="dot dot-improve"></span>改进
{% elif section.type == "修复" %}
<span class="dot dot-fix"></span>问题修复
{% else %}
<span class="dot dot-improve"></span>{{ section.type }}
{% endif %}
</div>
<ul>
{% for item in section.items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</div>
</section>
<script>
(function() {
var platforms = {
web: { name: 'Web 版', desc: '浏览器直接访问,功能完整,无需下载安装。', icon: 'globe', btnText: '立即使用 Web 版', btnHref: 'https://jiu.51yanmei.com/app/', available: true },
ios: { name: 'iOS', desc: 'iOS 客户端正在开发中,敬请期待。', icon: 'smartphone', btnText: '敬请期待', available: false },
android: { name: 'Android', desc: 'Android 客户端正在开发中,敬请期待。', icon: 'tablet-smartphone', btnText: '敬请期待', available: false },
windows: { name: 'Windows 桌面', desc: '原生桌面客户端,支持 Win 10/11(64 位),离线模式与本地打印。', icon: 'monitor', btnText: '下载 Windows 版', btnHref: '#', available: true },
macos: { name: 'macOS 桌面', desc: '支持 Apple Silicon 与 Intel,解压即用,首次运行右键→打开。', icon: 'laptop', btnText: '下载 macOS 版', btnHref: '#', available: true }
};
function detectPlatform() {
var ua = navigator.userAgent;
if (/iPhone|iPad|iPod/.test(ua)) return 'ios';
if (/Android/.test(ua)) return 'android';
var platform = navigator.platform || '';
if (/Win/.test(platform) || /Win/.test(ua)) return 'windows';
if (/Mac/.test(platform) || /Mac/.test(ua)) return 'macos';
return 'web';
}
function updateDetectCard(p) {
var info = platforms[p];
var nameEl = document.getElementById('detect-name');
var descEl = document.getElementById('detect-desc');
var btnEl = document.getElementById('detect-btn');
var iconEl = document.getElementById('detect-icon');
if (nameEl) nameEl.textContent = info.name;
if (descEl) descEl.textContent = info.desc;
if (btnEl) {
if (info.available) {
btnEl.href = info.btnHref;
btnEl.style.opacity = '';
btnEl.style.pointerEvents = '';
btnEl.querySelector('span') && (btnEl.querySelector('span').textContent = info.btnText);
} else {
btnEl.href = '#';
btnEl.style.opacity = '0.5';
btnEl.style.pointerEvents = 'none';
}
btnEl.childNodes.forEach(function(n) {
if (n.nodeType === 3) n.textContent = ' ' + info.btnText;
});
}
if (iconEl && window.lucide) {
iconEl.innerHTML = '';
var svg = document.createElement('i');
svg.setAttribute('data-lucide', info.icon);
svg.className = 'icon';
iconEl.appendChild(svg);
lucide.createIcons();
}
}
function highlightPlatformCard(p) {
document.querySelectorAll('#platform-grid .dl-card').forEach(function(el) {
el.classList.remove('detected');
});
var card = document.querySelector('#platform-grid [data-platform="' + p + '"]');
if (card) card.classList.add('detected');
}
function updateVersionBadges(version) {
document.querySelectorAll('.version-badge').forEach(function(el) {
el.textContent = 'v' + version;
});
}
document.addEventListener('DOMContentLoaded', function() {
var detected = detectPlatform();
updateDetectCard(detected);
highlightPlatformCard(detected);
fetch('https://jiu.51yanmei.com/api/v1/public/release')
.then(function(r) { return r.json(); })
.then(function(data) {
if (data && data.version) updateVersionBadges(data.version);
if (data && data.download_urls && data.download_urls.macos) {
platforms.macos.btnHref = data.download_urls.macos;
var macBtn = document.getElementById('macos-dl-btn');
if (macBtn) macBtn.href = data.download_urls.macos;
if (detected === 'macos') updateDetectCard(detected);
}
if (data && data.download_urls && data.download_urls.windows) {
platforms.windows.btnHref = data.download_urls.windows;
var btn = document.getElementById('windows-dl-btn');
if (btn) btn.href = data.download_urls.windows;
if (detected === 'windows') updateDetectCard(detected);
}
})
.catch(function() {});
});
})();
</script>