30a8e791a3
- public_product_screen: 1:1 复刻设计稿,新增商品介绍、批次防伪(自定义圆形印章)、完整商品参数表、门店营业时间、页脚链接 - app_theme: 完整品牌色系(brand/gray/accent/semantic) - shop model: 新增 business_hours 字段,public 接口同步返回 - nginx: 新增 /product/ → Flutter app 扫码入口,修复 /docs /download html 后缀兼容 - web/: 新增宣传主页、功能页、文档页、扫码 HTML 及设计资源 - app_shell: 界面优化 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
191 lines
9.6 KiB
HTML
191 lines
9.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>下载 — 岩美酒库管理系统</title>
|
|
<meta name="description" content="下载岩美酒库管理系统客户端,支持 macOS 和 Windows。" />
|
|
<link rel="stylesheet" href="assets/colors_and_type.css" />
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<script src="https://unpkg.com/lucide@0.469.0/dist/umd/lucide.min.js"></script>
|
|
<style>
|
|
* { box-sizing: border-box; }
|
|
html, body { margin: 0; padding: 0; font-family: var(--font-sans); color: var(--fg-default); background: var(--bg-surface); -webkit-font-smoothing: antialiased; }
|
|
a { color: inherit; text-decoration: none; }
|
|
.container { max-width: 1200px; margin: 0 auto; padding: 0 32px; }
|
|
.btn { display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 18px; border-radius: var(--radius-md); font-size: 14px; font-weight: 500; border: 1px solid transparent; cursor: pointer; transition: background 120ms; white-space: nowrap; text-decoration: none; }
|
|
.btn-primary { background: var(--brand-500); color: #fff; }
|
|
.btn-primary:hover { background: var(--brand-600); }
|
|
.btn-secondary { background: var(--gray-0); color: var(--brand-900); border-color: var(--border-default); }
|
|
.btn-secondary:hover { background: var(--gray-50); }
|
|
.btn-lg { height: 48px; padding: 0 24px; font-size: 15px; }
|
|
.btn-disabled { opacity: 0.5; pointer-events: none; }
|
|
.icon { width: 18px; height: 18px; }
|
|
|
|
/* NAV */
|
|
.nav { position: sticky; top: 0; z-index: 50; background: rgba(255,255,255,0.88); backdrop-filter: blur(12px); border-bottom: 1px solid var(--border-subtle); }
|
|
.nav-inner { height: 64px; display: flex; align-items: center; justify-content: space-between; max-width: 1200px; margin: 0 auto; padding: 0 32px; }
|
|
.nav-brand { display: flex; align-items: center; gap: 10px; font-size: 18px; font-weight: 700; color: var(--brand-900); }
|
|
.nav-brand img { height: 30px; }
|
|
.nav-links { display: flex; gap: 2px; }
|
|
.nav-links a { padding: 7px 14px; border-radius: var(--radius-md); font-size: 14px; color: var(--gray-700); transition: background 120ms; }
|
|
.nav-links a:hover { background: var(--gray-100); }
|
|
.nav-cta { display: flex; gap: 10px; }
|
|
|
|
/* PAGE */
|
|
.page-hero { padding: 72px 0 56px; text-align: center; border-bottom: 1px solid var(--border-subtle); }
|
|
.eyebrow { font-size: 11px; font-weight: 600; letter-spacing: 0.12em; color: var(--brand-500); text-transform: uppercase; margin-bottom: 14px; }
|
|
.page-title { font-size: 40px; font-weight: 700; color: var(--brand-900); margin: 0 0 14px; }
|
|
.page-sub { font-size: 16px; color: var(--fg-muted); margin: 0; line-height: 1.6; }
|
|
|
|
/* LOADING / ERROR */
|
|
.state-loading { padding: 60px 0; text-align: center; color: var(--fg-muted); font-size: 14px; }
|
|
.state-error { padding: 60px 0; text-align: center; color: var(--danger-500); font-size: 14px; }
|
|
|
|
/* RELEASE */
|
|
.release-section { padding: 64px 0; }
|
|
.version-badge { display: inline-flex; align-items: center; gap: 8px; background: var(--brand-50); color: var(--brand-700); padding: 5px 14px; border-radius: var(--radius-pill); font-size: 13px; font-weight: 600; margin-bottom: 8px; }
|
|
.build-date { font-size: 13px; color: var(--fg-muted); margin-bottom: 40px; }
|
|
.platform-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
|
|
.platform-card { background: var(--gray-0); border: 1px solid var(--border-default); border-radius: 10px; padding: 28px 24px; }
|
|
.platform-card h3 { font-size: 18px; font-weight: 600; color: var(--brand-900); margin: 0 0 6px; display: flex; align-items: center; gap: 10px; }
|
|
.platform-card h3 i { width: 20px; height: 20px; color: var(--brand-500); }
|
|
.platform-card p { font-size: 13px; color: var(--fg-muted); margin: 0 0 24px; line-height: 1.6; }
|
|
.web-badge { display: inline-flex; align-items: center; gap: 6px; background: var(--success-50); color: var(--success-700); padding: 3px 10px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 600; margin-bottom: 6px; }
|
|
|
|
/* CHANGELOG */
|
|
.changelog-section { padding: 0 0 64px; }
|
|
.changelog-title { font-size: 20px; font-weight: 600; color: var(--brand-900); margin: 0 0 20px; }
|
|
.changelog-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
|
|
.changelog-item { display: flex; gap: 14px; background: var(--gray-0); border: 1px solid var(--border-default); border-radius: 8px; padding: 16px 20px; }
|
|
.changelog-ver { font-size: 13px; font-weight: 600; color: var(--brand-700); font-family: var(--font-mono); min-width: 60px; padding-top: 2px; }
|
|
.changelog-content { flex: 1; }
|
|
.changelog-date { font-size: 11px; color: var(--fg-subtle); margin-bottom: 6px; }
|
|
.changelog-notes { font-size: 13px; color: var(--fg-default); margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; }
|
|
.changelog-notes li::before { content: '· '; color: var(--brand-400); }
|
|
|
|
/* FOOTER */
|
|
footer { background: var(--gray-50); border-top: 1px solid var(--border-default); padding: 40px 0; }
|
|
.footer-inner { display: flex; align-items: center; justify-content: space-between; }
|
|
.footer-brand { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--brand-900); }
|
|
.footer-brand img { height: 24px; }
|
|
.footer-copy { font-size: 12px; color: var(--fg-subtle); }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<nav class="nav">
|
|
<div class="nav-inner">
|
|
<a href="/" class="nav-brand"><img src="assets/logo-full.svg" alt="岩美" /></a>
|
|
<div class="nav-links">
|
|
<a href="/features/inventory.html">功能</a>
|
|
<a href="/docs.html">文档</a>
|
|
<a href="/download.html">下载</a>
|
|
</div>
|
|
<div class="nav-cta">
|
|
<a href="/app/" class="btn btn-primary">进入管理端 <i data-lucide="arrow-right" class="icon"></i></a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="page-hero">
|
|
<div class="container">
|
|
<div class="eyebrow">Download</div>
|
|
<h1 class="page-title">下载岩美客户端</h1>
|
|
<p class="page-sub">支持 macOS、Windows 桌面端,以及通过浏览器直接使用的 Web 版本。</p>
|
|
</div>
|
|
</div>
|
|
|
|
<section class="release-section">
|
|
<div class="container" id="release-container">
|
|
<div class="state-loading">正在获取版本信息...</div>
|
|
</div>
|
|
</section>
|
|
|
|
<footer>
|
|
<div class="container">
|
|
<div class="footer-inner">
|
|
<div class="footer-brand"><img src="assets/logo-mark.svg" alt="岩美" /> 岩美酒库管理系统</div>
|
|
<div class="footer-copy">© 2025 岩美。保留所有权利。</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
lucide.createIcons();
|
|
|
|
const API_BASE = location.hostname === 'localhost' ? 'http://localhost:8080/api/v1' : '/api/v1';
|
|
|
|
function fmt(d) {
|
|
if (!d) return '—';
|
|
return d.replace(/(\d{4})-(\d{2})-(\d{2})/, '$1 年 $2 月 $3 日');
|
|
}
|
|
|
|
function renderRelease(r) {
|
|
const dl = r.download_urls || {};
|
|
const container = document.getElementById('release-container');
|
|
container.innerHTML = `
|
|
<div class="version-badge">
|
|
<i data-lucide="tag" style="width:14px;height:14px"></i>
|
|
v${r.version || '—'}
|
|
</div>
|
|
<div class="build-date">发布日期:${fmt(r.build_date)}</div>
|
|
<div class="platform-grid">
|
|
<div class="platform-card">
|
|
<h3><i data-lucide="monitor"></i> macOS</h3>
|
|
<p>适用于 Apple Silicon / Intel Mac。支持本地打印与快捷键操作。</p>
|
|
${dl.macos
|
|
? `<a href="${dl.macos}" class="btn btn-primary btn-lg"><i data-lucide="download" class="icon"></i> 下载 macOS</a>`
|
|
: `<span class="btn btn-secondary btn-lg btn-disabled"><i data-lucide="clock" class="icon"></i> 暂未发布</span>`}
|
|
</div>
|
|
<div class="platform-card">
|
|
<h3><i data-lucide="monitor"></i> Windows</h3>
|
|
<p>适用于 Windows 10 及以上版本,支持本地打印机直连。</p>
|
|
${dl.windows
|
|
? `<a href="${dl.windows}" class="btn btn-primary btn-lg"><i data-lucide="download" class="icon"></i> 下载 Windows</a>`
|
|
: `<span class="btn btn-secondary btn-lg btn-disabled"><i data-lucide="clock" class="icon"></i> 暂未发布</span>`}
|
|
</div>
|
|
<div class="platform-card">
|
|
<h3><i data-lucide="globe"></i> Web 版本</h3>
|
|
<span class="web-badge"><i data-lucide="zap" style="width:11px;height:11px"></i> 无需安装</span>
|
|
<p>直接在浏览器中使用全功能管理端,推荐 Chrome / Edge。</p>
|
|
<a href="/app/" class="btn btn-primary btn-lg"><i data-lucide="external-link" class="icon"></i> 打开 Web 版</a>
|
|
</div>
|
|
</div>
|
|
${renderChangelog(r.changelog)}
|
|
`;
|
|
lucide.createIcons();
|
|
}
|
|
|
|
function renderChangelog(list) {
|
|
if (!list || list.length === 0) return '';
|
|
const items = list.map(v => `
|
|
<li class="changelog-item">
|
|
<div class="changelog-ver">v${v.version}</div>
|
|
<div class="changelog-content">
|
|
<div class="changelog-date">${fmt(v.date)}</div>
|
|
<ul class="changelog-notes">${(v.items||[]).map(i=>`<li>${i}</li>`).join('')}</ul>
|
|
</div>
|
|
</li>
|
|
`).join('');
|
|
return `
|
|
<div class="changelog-section" style="margin-top:48px">
|
|
<h2 class="changelog-title">更新日志</h2>
|
|
<ul class="changelog-list">${items}</ul>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
fetch(`${API_BASE}/public/release`)
|
|
.then(r => r.json())
|
|
.then(renderRelease)
|
|
.catch(err => {
|
|
document.getElementById('release-container').innerHTML =
|
|
`<div class="state-error">无法获取版本信息,请稍后再试。<br/><small>${err.message}</small></div>`;
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|