Files
jiu/web/docs.njk
T
wangjia c0001f08c2 fix(web): 官网 todo 清单全量修复(联系方式/死链/按钮/导航/下载)
- 联系方式:site.json email 改为真实地址,移除假电话,页脚条件渲染
- 死链:功能页 /download.html → /download/,页脚 href="#" 全部落地或移除
- 按钮指向:价格「购买」→ /register/,「联系销售/演示」→ mailto
- 导航:新增库存管理、审核流直链;模块卡加「了解更多」入口
- iOS 矛盾:首页平台卡标注「TestFlight 内测中」与下载页对齐
- 下载:API 域名抽到 site.json;接口失败时按钮降级为禁用态
- FAQ:试用版/单店版口径统一,明确「注册即试用 30 天」
- 文档:⌘K/Ctrl+K 绑定聚焦搜索框;反馈按钮改为本地 UI,不调不存在的接口
- dist:清理旧 docs.html 残留

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 21:13:19 +08:00

201 lines
6.5 KiB
Plaintext

---
layout: base.njk
title: 使用手册
description: 岩美酒库管理系统使用手册,覆盖入库、出库、库存、财务等全功能操作说明。
pageExtraCss: /assets/docs.css
---
<!-- ============================== DOCS SUB-NAV ============================== -->
<div class="docs-subnav">
<div class="docs-subnav-inner">
<nav class="breadcrumb">
<a href="/">岩美</a>
<span class="sep">/</span>
<span class="current">使用手册</span>
</nav>
<div class="docs-search">
<i data-lucide="search" class="search-icon icon"></i>
<input type="text" placeholder="搜索文档..." id="docs-search-input" />
<span class="kbd">⌘K</span>
</div>
<div class="docs-version">
<i data-lucide="tag" class="icon"></i>
<span class="docs-version-label">版本</span>
<span>v{{ changelog[0].version }}</span>
</div>
</div>
</div>
<!-- ============================== THREE-COLUMN LAYOUT ============================== -->
<div class="docs-layout">
<!-- Left TOC -->
<aside class="docs-toc" id="docs-toc">
{% for group in docs.toc %}
<div class="toc-section">
<div class="toc-section-title">{{ group.group }}</div>
{% for item in group.items %}
<a href="#{{ item.id }}" class="toc-link" data-chapter="{{ item.id }}">
<span class="toc-num">{{ item.num }}</span>
{{ item.title }}
</a>
{% endfor %}
</div>
{% endfor %}
</aside>
<!-- Main content -->
<main class="docs-main" id="docs-main">
{% for chapter in docs.chapters %}
<section class="docs-chapter" id="{{ chapter.id }}">
<h2>{{ chapter.num }}. {{ chapter.title }}</h2>
{{ chapter.html | safe }}
</section>
{% endfor %}
<div class="docs-feedback">
<span class="feedback-q">这篇文档对您有帮助吗?</span>
<div class="feedback-actions">
<button class="feedback-btn" onclick="sendFeedback('yes')">
<i data-lucide="thumbs-up" class="icon"></i>有帮助
</button>
<button class="feedback-btn" onclick="sendFeedback('no')">
<i data-lucide="thumbs-down" class="icon"></i>需要改进
</button>
</div>
</div>
</main>
<!-- Right rail -->
<aside class="docs-rail" id="docs-rail">
<div class="rail-title">本页目录</div>
<ul class="rail-list" id="rail-list"></ul>
<div class="rail-actions">
<button class="rail-action" onclick="window.print()">
<i data-lucide="printer" class="icon"></i>打印此页
</button>
<button class="rail-action" id="copy-link-btn">
<i data-lucide="link" class="icon"></i>复制链接
</button>
<a class="rail-action" href="#ch-1">
<i data-lucide="arrow-up" class="icon"></i>回到顶部
</a>
</div>
</aside>
</div>
<script>
(function() {
var chapters = document.querySelectorAll('.docs-chapter');
var tocLinks = document.querySelectorAll('.toc-link');
var railList = document.getElementById('rail-list');
// Build right rail from all chapter h2+h3 headings
function buildRail() {
var items = [];
chapters.forEach(function(ch) {
var chId = ch.id;
var chTitle = ch.querySelector('h2');
if (chTitle) {
items.push({ id: chId, text: chTitle.textContent, level: 2 });
}
ch.querySelectorAll('h3').forEach(function(h3) {
if (!h3.id) {
h3.id = chId + '-' + h3.textContent.replace(/\s+/g, '-').replace(/[^\w\-]/g, '').toLowerCase();
}
items.push({ id: h3.id, text: h3.textContent, level: 3 });
});
});
railList.innerHTML = items.map(function(item) {
var indent = item.level === 3 ? ' style="padding-left:20px;"' : '';
return '<li><a href="#' + item.id + '"' + indent + '>' + item.text + '</a></li>';
}).join('');
}
// Scrollspy: highlight active TOC link and rail link
function setupScrollspy() {
if (!window.IntersectionObserver) return;
var activeChapterId = null;
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
activeChapterId = entry.target.id;
}
});
if (!activeChapterId) return;
// Update left TOC
tocLinks.forEach(function(link) {
var isActive = link.getAttribute('data-chapter') === activeChapterId;
link.classList.toggle('active', isActive);
});
// Update rail links
railList.querySelectorAll('a').forEach(function(a) {
a.classList.remove('active');
if (a.getAttribute('href') === '#' + activeChapterId) {
a.classList.add('active');
}
});
}, { rootMargin: '-20% 0px -70% 0px', threshold: 0 });
chapters.forEach(function(ch) { observer.observe(ch); });
}
// ⌘K / Ctrl+K 聚焦搜索框
document.addEventListener('keydown', function(e) {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
var inp = document.getElementById('docs-search-input');
if (inp) { e.preventDefault(); inp.focus(); inp.select(); }
}
});
// Simple search: highlight matching text in main content
var searchInput = document.getElementById('docs-search-input');
if (searchInput) {
searchInput.addEventListener('input', function() {
var q = this.value.trim().toLowerCase();
if (!q) {
chapters.forEach(function(ch) { ch.style.display = ''; });
return;
}
chapters.forEach(function(ch) {
var text = ch.textContent.toLowerCase();
ch.style.display = text.includes(q) ? '' : 'none';
});
});
}
// Copy link button
var copyBtn = document.getElementById('copy-link-btn');
if (copyBtn) {
copyBtn.addEventListener('click', function() {
navigator.clipboard.writeText(window.location.href).then(function() {
copyBtn.querySelector('span, .icon') && null;
var orig = copyBtn.innerHTML;
copyBtn.innerHTML = '<i data-lucide="check" class="icon"></i>已复制';
if (window.lucide) lucide.createIcons();
setTimeout(function() { copyBtn.innerHTML = orig; if (window.lucide) lucide.createIcons(); }, 2000);
});
});
}
function sendFeedback(val) {
var fb = document.querySelector('.docs-feedback');
if (fb) fb.innerHTML = '<span style="color:var(--success-700);font-size:var(--text-md);">感谢您的反馈!</span>';
}
window.sendFeedback = sendFeedback;
document.addEventListener('DOMContentLoaded', function() {
buildRail();
setupScrollspy();
if (window.lucide) lucide.createIcons();
});
})();
</script>