Files
jiu/web/features/inventory.html
T
wangjia b90a89790f feat(web): 五个营销页面完整还原设计稿
统一 nav(5 个链接含支持、auth-aware 用户下拉菜单)、
docs 页补充面包屑/搜索/版本栏三栏布局、
footer 完整 5 列、所有内链替换为生产绝对路径。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:57:32 +08:00

1459 lines
56 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>库存管理 · 岩美酒库管理系统</title>
<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&family=JetBrains+Mono:wght@400;500;600&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;
text-rendering: optimizeLegibility;
font-feature-settings: "tnum" 1;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
.btn {
display: inline-flex; align-items: center; gap: 8px;
height: 40px; padding: 0 18px;
border-radius: var(--radius-md);
font-size: var(--text-md); font-weight: 500;
border: 1px solid transparent;
transition: background var(--duration-fast) var(--ease-standard);
white-space: nowrap;
}
.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); border-color: var(--border-strong); }
.btn-ghost { background: transparent; color: var(--fg-default); }
.btn-ghost:hover { background: var(--gray-100); }
.btn-lg { height: 48px; padding: 0 24px; font-size: var(--text-lg); }
.btn .icon { width: 18px; height: 18px; }
.container { max-width: 1280px; margin: 0 auto; padding: 0 32px; }
.section { padding: 96px 0; }
.eyebrow {
font-size: var(--text-xs); font-weight: 600;
letter-spacing: 0.12em; text-transform: uppercase;
color: var(--brand-500); margin: 0 0 12px;
}
/* Top Nav */
.topnav { position: sticky; top: 0; z-index: 50; background: rgba(255,255,255,0.85); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-bottom: 1px solid var(--border-subtle); }
.topnav-inner { height: 64px; display: flex; align-items: center; justify-content: space-between; max-width: 1440px; margin: 0 auto; padding: 0 32px; }
.topnav-brand { display: flex; align-items: center; gap: 10px; }
.topnav-brand img { height: 32px; }
.topnav-links { display: flex; align-items: center; gap: 4px; font-size: var(--text-md); color: var(--gray-700); }
.topnav-links a { padding: 8px 14px; border-radius: var(--radius-md); transition: background var(--duration-fast) var(--ease-standard); }
.topnav-links a:hover { background: var(--gray-100); color: var(--brand-900); }
.topnav-links a.active { color: var(--brand-500); background: var(--brand-50); }
.topnav-cta { display: flex; gap: 10px; align-items: center; }
/* Nav user dropdown */
.nav-user { position: relative; }
.nav-user-btn {
display: flex; align-items: center; gap: 8px;
height: 36px; padding: 0 12px 0 8px;
border-radius: var(--radius-md);
border: 1px solid var(--border-default);
background: var(--gray-0);
font-size: var(--text-sm); color: var(--gray-800);
cursor: pointer;
transition: background var(--duration-fast) var(--ease-standard);
}
.nav-user-btn:hover { background: var(--gray-50); }
.nav-avatar {
width: 22px; height: 22px; border-radius: 50%;
background: var(--brand-500); color: #fff;
font-size: 11px; font-weight: 700;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.nav-user-btn .icon { width: 14px; height: 14px; color: var(--fg-muted); }
.nav-dropdown {
display: none; position: absolute; top: calc(100% + 8px); right: 0;
min-width: 200px;
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
padding: 6px;
z-index: 100;
}
.nav-dropdown.open { display: block; }
.nav-dropdown-info {
padding: 8px 10px 10px;
border-bottom: 1px solid var(--border-subtle);
margin-bottom: 6px;
}
.nav-dropdown-name { font-size: var(--text-sm); font-weight: 600; color: var(--brand-900); }
.nav-dropdown-role { font-size: 11px; color: var(--fg-muted); margin-top: 2px; }
.nav-dropdown a, .nav-dropdown button {
display: flex; align-items: center; gap: 8px;
width: 100%; padding: 8px 10px;
border-radius: var(--radius-md);
font-size: var(--text-sm); color: var(--gray-700);
background: none; border: none; text-align: left; cursor: pointer;
transition: background var(--duration-fast) var(--ease-standard);
}
.nav-dropdown a:hover, .nav-dropdown button:hover { background: var(--gray-50); color: var(--brand-900); }
.nav-dropdown .icon { width: 15px; height: 15px; color: var(--fg-muted); }
.nav-dropdown .logout { color: var(--danger-600); }
.nav-dropdown .logout .icon { color: var(--danger-400); }
/* ====================================================================
HERO
==================================================================== */
.feat-hero {
position: relative; overflow: hidden;
padding: 80px 0 72px;
background:
radial-gradient(1000px 480px at 88% 8%, rgba(37, 99, 172, 0.08), transparent 60%),
linear-gradient(180deg, #FBFCFD 0%, #FFFFFF 80%);
border-bottom: 1px solid var(--border-subtle);
}
.feat-hero-inner {
display: grid;
grid-template-columns: 1fr 1.15fr;
gap: 56px;
align-items: center;
}
.feat-breadcrumb {
display: flex; align-items: center; gap: 8px;
font-size: var(--text-sm); color: var(--fg-muted);
margin-bottom: 20px;
}
.feat-breadcrumb a { color: var(--fg-muted); }
.feat-breadcrumb a:hover { color: var(--brand-500); }
.feat-breadcrumb .icon { width: 14px; height: 14px; color: var(--gray-300); }
.feat-hero h1 {
font-size: 48px; line-height: 1.15;
letter-spacing: var(--tracking-cn-display);
color: var(--brand-900); margin: 0 0 18px;
font-weight: 700;
}
.feat-hero p.lead {
font-size: var(--text-xl); line-height: 1.6;
color: var(--gray-600); margin: 0 0 28px;
}
.feat-hero .actions { display: flex; gap: 12px; margin-bottom: 28px; }
.feat-hero .quick-stats {
display: grid; grid-template-columns: repeat(3, 1fr);
gap: 0; border-top: 1px solid var(--border-subtle);
padding-top: 20px;
}
.feat-hero .quick-stat-label { font-size: 11px; color: var(--fg-subtle); letter-spacing: 0.04em; }
.feat-hero .quick-stat-val { font-size: var(--text-xl); font-weight: 600; color: var(--brand-900); font-variant-numeric: tabular-nums; margin-top: 4px; }
/* Hero composite: stacked cards */
.composite { position: relative; height: 540px; }
.composite-card {
position: absolute;
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
overflow: hidden;
}
.composite-main { top: 0; left: 0; right: 60px; bottom: 60px; box-shadow: var(--shadow-xl); }
.composite-secondary { right: 0; top: 70px; width: 240px; padding: 16px; box-shadow: var(--shadow-lg); }
.composite-tertiary { left: 80px; bottom: 0; right: 0; padding: 14px; box-shadow: var(--shadow-md); }
.mc-head {
padding: 12px 16px;
background: var(--gray-50);
border-bottom: 1px solid var(--border-subtle);
display: flex; justify-content: space-between; align-items: center;
}
.mc-title { font-size: 13px; font-weight: 600; color: var(--brand-900); }
.mc-tabs { display: flex; gap: 4px; }
.mc-tab { padding: 3px 10px; font-size: 11px; color: var(--fg-muted); border-radius: var(--radius-sm); }
.mc-tab.active { background: var(--gray-0); color: var(--brand-700); border: 1px solid var(--brand-200); }
.mc-stats { display: grid; grid-template-columns: repeat(3, 1fr); padding: 14px 16px; gap: 10px; border-bottom: 1px solid var(--border-subtle); background: var(--gray-25); }
.mc-stat-label { font-size: 10px; color: var(--fg-subtle); margin-bottom: 2px; }
.mc-stat-val { font-size: 16px; font-weight: 600; color: var(--brand-900); font-variant-numeric: tabular-nums; }
.mc-stat-val .delta { font-size: 10px; color: var(--success-500); margin-left: 4px; font-weight: 500; }
.mc-table { font-size: 11px; }
.mc-thead, .mc-trow {
display: grid;
grid-template-columns: 88px 1fr 50px 60px 60px 70px;
padding: 8px 16px;
gap: 8px;
align-items: center;
font-variant-numeric: tabular-nums;
}
.mc-thead { background: var(--gray-50); font-size: 10px; font-weight: 500; color: var(--fg-muted); border-bottom: 1px solid var(--border-subtle); }
.mc-trow { border-bottom: 1px solid var(--border-subtle); color: var(--gray-800); }
.mc-trow:last-child { border-bottom: none; }
.mc-trow .sku { font-family: var(--font-mono); color: var(--brand-500); font-size: 10px; }
.mc-pill { display: inline-block; padding: 1px 7px; border-radius: var(--radius-pill); font-size: 9px; font-weight: 500; }
.mc-pill.ok { background: var(--success-50); color: var(--success-700); }
.mc-pill.warn { background: var(--warning-50); color: var(--warning-700); }
.mc-pill.low { background: var(--danger-50); color: var(--danger-700); }
/* Alert card secondary */
.alert-card-title { font-size: 11px; color: var(--fg-muted); margin-bottom: 8px; letter-spacing: 0.04em; }
.alert-row {
display: flex; justify-content: space-between; align-items: center;
padding: 8px 10px;
background: var(--warning-50);
border-left: 2px solid var(--warning-500);
border-radius: 3px;
margin-bottom: 6px;
font-size: 12px;
}
.alert-row.danger { background: var(--danger-50); border-color: var(--danger-500); }
.alert-row .name { color: var(--gray-900); font-weight: 500; flex: 1; }
.alert-row .qty { color: var(--gray-700); font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-size: 11px; }
/* Batch card (tertiary) */
.batch-title { font-size: 11px; color: var(--fg-muted); margin-bottom: 6px; letter-spacing: 0.04em; display: flex; align-items: center; gap: 6px; }
.batch-title .icon { width: 12px; height: 12px; color: var(--brand-500); }
.batch-row {
display: grid;
grid-template-columns: 90px 1fr 60px 50px;
font-size: 11px;
padding: 6px 0;
border-bottom: 1px dashed var(--border-subtle);
align-items: center;
font-variant-numeric: tabular-nums;
}
.batch-row:last-child { border-bottom: none; }
.batch-row .lot { font-family: var(--font-mono); color: var(--brand-600); font-size: 10px; }
.batch-row .meta { color: var(--fg-muted); font-size: 10px; }
/* ====================================================================
FEATURE BLOCKS
==================================================================== */
.feat-block {
padding: 96px 0;
border-bottom: 1px solid var(--border-subtle);
}
.feat-block:nth-child(even) { background: var(--gray-25); }
.feat-block-inner {
display: grid;
grid-template-columns: 5fr 7fr;
gap: 64px;
align-items: center;
}
.feat-block.reverse .feat-block-inner { grid-template-columns: 7fr 5fr; }
.feat-block.reverse .feat-text { order: 2; }
.feat-block.reverse .feat-visual { order: 1; }
.feat-tag {
display: inline-flex; align-items: center; gap: 6px;
background: var(--brand-50);
color: var(--brand-700);
padding: 4px 10px;
border-radius: var(--radius-pill);
font-size: var(--text-xs);
font-weight: 600;
letter-spacing: 0.04em;
margin-bottom: 16px;
}
.feat-tag .icon { width: 14px; height: 14px; }
.feat-text h2 {
font-size: 36px;
font-weight: 600;
line-height: 1.18;
letter-spacing: var(--tracking-cn-display);
color: var(--brand-900);
margin: 0 0 16px;
}
.feat-text p.lead {
font-size: var(--text-lg);
line-height: 1.7;
color: var(--gray-600);
margin: 0 0 24px;
}
.feat-bullets { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 14px; }
.feat-bullets li {
display: grid;
grid-template-columns: 22px 1fr;
gap: 12px;
font-size: var(--text-md);
color: var(--gray-700);
line-height: 1.6;
align-items: start;
}
.feat-bullets li .icon { width: 18px; height: 18px; color: var(--brand-500); margin-top: 2px; }
.feat-bullets li strong { color: var(--brand-900); font-weight: 600; display: block; margin-bottom: 2px; }
/* Visual primitives */
.visual-card {
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
overflow: hidden;
}
.visual-card-head {
padding: 14px 18px;
background: var(--gray-50);
border-bottom: 1px solid var(--border-subtle);
display: flex; justify-content: space-between; align-items: center;
}
.visual-card-title { font-size: var(--text-sm); font-weight: 600; color: var(--brand-900); }
.visual-card-meta { font-size: 11px; color: var(--fg-muted); }
/* Inventory table visual */
.inv-table { font-size: var(--text-sm); }
.inv-table-row {
display: grid;
grid-template-columns: 110px 1fr 70px 80px 80px 110px;
padding: 12px 18px;
gap: 12px;
border-bottom: 1px solid var(--border-subtle);
align-items: center;
font-variant-numeric: tabular-nums;
}
.inv-table-row.head {
background: var(--gray-50);
font-size: 11px; font-weight: 500;
color: var(--fg-muted);
letter-spacing: 0.02em;
padding: 10px 18px;
}
.inv-table-row:last-child { border-bottom: none; }
.inv-table-row:hover:not(.head) { background: var(--gray-25); }
.inv-table-row .sku { font-family: var(--font-mono); color: var(--brand-500); font-size: 12px; }
.inv-table-row .name { color: var(--gray-900); font-weight: 500; }
.inv-table-row .name small { display: block; color: var(--fg-muted); font-weight: 400; font-size: 11px; margin-top: 1px; }
/* Batch tracking visual — journey */
.batch-journey {
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
padding: 28px;
}
.batch-journey-head {
display: flex; justify-content: space-between; align-items: flex-start;
margin-bottom: 24px;
padding-bottom: 18px;
border-bottom: 1px solid var(--border-subtle);
}
.bj-meta-main { font-size: var(--text-sm); }
.bj-lot { font-family: var(--font-mono); font-size: var(--text-xl); font-weight: 600; color: var(--brand-700); margin-bottom: 4px; }
.bj-product { font-size: var(--text-md); color: var(--gray-900); font-weight: 500; }
.bj-product small { color: var(--fg-muted); font-weight: 400; margin-left: 8px; }
.bj-totals { text-align: right; }
.bj-total-row { font-size: var(--text-xs); color: var(--fg-muted); display: flex; gap: 8px; justify-content: flex-end; margin-bottom: 4px; }
.bj-total-row strong { color: var(--gray-900); font-weight: 600; font-variant-numeric: tabular-nums; }
.bj-progress {
background: var(--gray-100);
height: 8px;
border-radius: var(--radius-pill);
margin-bottom: 24px;
position: relative;
overflow: hidden;
}
.bj-progress-bar {
height: 100%;
background: linear-gradient(90deg, var(--brand-500), var(--brand-400));
width: 67%;
border-radius: var(--radius-pill);
}
.bj-progress-labels { display: flex; justify-content: space-between; margin-top: -16px; }
.bj-progress-labels span { font-size: 11px; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.bj-timeline { display: flex; flex-direction: column; gap: 0; }
.bj-event {
display: grid;
grid-template-columns: 16px 110px 1fr 80px 90px;
gap: 16px;
padding: 12px 0;
align-items: center;
border-bottom: 1px solid var(--border-subtle);
position: relative;
}
.bj-event:last-child { border-bottom: none; }
.bj-event-dot {
width: 10px; height: 10px;
border-radius: 50%;
background: var(--gray-300);
margin: 0 auto;
}
.bj-event.stockin .bj-event-dot { background: var(--brand-500); box-shadow: 0 0 0 4px var(--brand-50); }
.bj-event.stockout .bj-event-dot { background: var(--accent-500); }
.bj-event.adjust .bj-event-dot { background: var(--warning-500); }
.bj-event-date { font-size: 11px; color: var(--fg-muted); font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.bj-event-desc { font-size: var(--text-sm); color: var(--gray-800); }
.bj-event-desc small { display: block; color: var(--fg-muted); font-size: 11px; margin-top: 2px; }
.bj-event-qty { font-size: var(--text-md); font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
.bj-event.stockin .bj-event-qty { color: var(--success-700); }
.bj-event.stockout .bj-event-qty { color: var(--accent-500); }
.bj-event-doc { font-size: 11px; color: var(--brand-500); font-family: var(--font-mono); text-align: right; }
/* Stocktake comparison */
.stocktake-table {
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-md);
}
.st-summary {
display: grid; grid-template-columns: repeat(4, 1fr);
padding: 18px 20px;
background: var(--brand-900);
color: #fff;
gap: 16px;
}
.st-summary-item .label { font-size: 11px; color: #ADC9EA; margin-bottom: 4px; letter-spacing: 0.04em; }
.st-summary-item .val { font-size: var(--text-xl); font-weight: 600; font-variant-numeric: tabular-nums; }
.st-summary-item .val.neg { color: var(--danger-500); }
.st-row {
display: grid;
grid-template-columns: 1fr 70px 70px 80px 90px;
padding: 12px 20px;
gap: 12px;
border-bottom: 1px solid var(--border-subtle);
font-size: var(--text-sm);
align-items: center;
font-variant-numeric: tabular-nums;
}
.st-row:last-child { border-bottom: none; }
.st-row.head { background: var(--gray-50); font-size: 11px; color: var(--fg-muted); font-weight: 500; }
.st-row.head > div { text-align: right; }
.st-row.head > div:first-child { text-align: left; }
.st-row .diff-pill {
display: inline-block;
padding: 2px 8px;
border-radius: var(--radius-pill);
font-size: 11px;
font-weight: 600;
}
.st-row .diff-pill.zero { background: var(--gray-100); color: var(--gray-700); }
.st-row .diff-pill.neg { background: var(--danger-50); color: var(--danger-700); }
.st-row .diff-pill.pos { background: var(--success-50); color: var(--success-700); }
.st-row > div:not(:first-child) { text-align: right; }
/* Log timeline */
.log-card {
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
overflow: hidden;
}
.log-toolbar {
display: flex; gap: 8px; padding: 12px 18px;
background: var(--gray-50);
border-bottom: 1px solid var(--border-subtle);
align-items: center;
font-size: var(--text-xs);
color: var(--fg-muted);
}
.log-filter-pill {
display: inline-flex; align-items: center; gap: 4px;
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-pill);
padding: 3px 10px;
font-size: 11px;
color: var(--gray-700);
}
.log-filter-pill.active { background: var(--brand-50); border-color: var(--brand-300); color: var(--brand-700); }
.log-filter-pill .icon { width: 12px; height: 12px; }
.log-row {
display: grid;
grid-template-columns: 100px 60px 1fr 60px 80px;
padding: 12px 18px;
gap: 14px;
border-bottom: 1px solid var(--border-subtle);
font-size: var(--text-sm);
align-items: center;
font-variant-numeric: tabular-nums;
}
.log-row:last-child { border-bottom: none; }
.log-time { font-family: var(--font-mono); font-size: 11px; color: var(--fg-muted); }
.log-type-pill {
display: inline-block;
padding: 1px 8px;
border-radius: var(--radius-pill);
font-size: 10px;
font-weight: 500;
}
.log-type-pill.in { background: var(--success-50); color: var(--success-700); }
.log-type-pill.out { background: var(--accent-50); color: var(--accent-700); }
.log-type-pill.check { background: var(--info-50); color: var(--info-700); }
.log-desc { color: var(--gray-800); font-size: 13px; }
.log-desc small { color: var(--fg-muted); display: block; font-size: 11px; margin-top: 1px; }
.log-qty { text-align: right; font-weight: 600; }
.log-qty.in { color: var(--success-700); }
.log-qty.out { color: var(--accent-500); }
.log-op { text-align: right; font-size: 12px; color: var(--gray-700); }
/* Alert config */
.alert-config-card {
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
padding: 24px;
}
.alert-config-card h4 {
margin: 0 0 4px;
font-size: var(--text-md);
font-weight: 600;
color: var(--brand-900);
}
.alert-config-card p.sub { margin: 0 0 20px; font-size: var(--text-sm); color: var(--fg-muted); }
.threshold-bar {
position: relative;
height: 56px;
margin: 28px 0 12px;
}
.threshold-track {
position: absolute; top: 24px; left: 0; right: 0;
height: 8px;
background: linear-gradient(90deg, var(--danger-100, #FBC9C9) 0%, var(--danger-100, #FBC9C9) 18%, var(--warning-50) 18%, var(--warning-50) 42%, var(--success-50) 42%, var(--success-50) 100%);
border-radius: var(--radius-pill);
}
.threshold-marker {
position: absolute; top: 18px;
width: 20px; height: 20px;
border-radius: 50%;
background: var(--gray-0);
border: 3px solid var(--brand-500);
transform: translateX(-50%);
box-shadow: 0 2px 6px rgba(20,24,33,0.10);
}
.threshold-tick {
position: absolute;
top: 38px;
transform: translateX(-50%);
font-size: 10px;
color: var(--fg-muted);
font-family: var(--font-mono);
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.threshold-label {
position: absolute;
bottom: 8px;
transform: translateX(-50%);
font-size: 10px;
color: var(--fg-muted);
letter-spacing: 0.04em;
white-space: nowrap;
}
.alert-rules { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }
.alert-rule {
display: flex; justify-content: space-between; align-items: center;
padding: 10px 14px;
background: var(--gray-25);
border-radius: var(--radius-md);
font-size: 13px;
color: var(--gray-700);
}
.alert-rule strong { color: var(--brand-900); font-weight: 600; }
.alert-rule .switch {
width: 32px; height: 18px;
background: var(--brand-500);
border-radius: var(--radius-pill);
position: relative;
}
.alert-rule .switch::after {
content: '';
position: absolute;
top: 2px; right: 2px;
width: 14px; height: 14px;
background: #fff;
border-radius: 50%;
}
.alert-rule .switch.off { background: var(--gray-300); }
.alert-rule .switch.off::after { right: auto; left: 2px; }
/* Use cases */
.usecases-grid {
display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
margin-top: 48px;
}
.usecase-card {
background: var(--gray-0);
border: 1px solid var(--border-default);
border-radius: var(--radius-lg);
padding: 28px;
}
.usecase-card .icon {
width: 36px; height: 36px; color: var(--brand-500); margin-bottom: 16px;
}
.usecase-card h4 { margin: 0 0 8px; font-size: var(--text-lg); font-weight: 600; color: var(--brand-900); }
.usecase-card p { margin: 0; font-size: var(--text-sm); color: var(--gray-700); line-height: 1.65; }
/* Final CTA */
.cta-strip {
background: linear-gradient(135deg, #0A1F3B 0%, #15407D 100%);
color: #fff;
border-radius: var(--radius-xl);
padding: 56px 48px;
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: 32px;
align-items: center;
margin: 0 0 96px;
}
.cta-strip h2 {
font-size: 32px; font-weight: 600;
letter-spacing: var(--tracking-cn-display);
color: #fff; margin: 0 0 12px; line-height: 1.25;
}
.cta-strip p { font-size: var(--text-md); color: #ADC9EA; margin: 0; line-height: 1.6; }
.cta-strip-actions { display: flex; flex-direction: column; gap: 10px; align-items: flex-end; }
.cta-strip .btn-primary { background: #fff; color: var(--brand-700); }
.cta-strip .btn-primary:hover { background: #DCE2EB; }
.cta-strip .btn-secondary { background: transparent; color: #fff; border-color: rgba(255,255,255,0.30); }
.cta-strip .btn-secondary:hover { background: rgba(255,255,255,0.10); }
/* Footer */
footer { background: var(--gray-25); border-top: 1px solid var(--border-subtle); padding: 64px 0 32px; color: var(--fg-muted); font-size: var(--text-sm); }
.footer-grid { display: grid; grid-template-columns: 1.5fr repeat(4, 1fr); gap: 48px; margin-bottom: 48px; }
.footer-brand img { height: 32px; margin-bottom: 16px; }
.footer-brand p { margin: 0 0 16px; max-width: 320px; line-height: 1.6; color: var(--fg-muted); }
.footer-contact { font-size: var(--text-sm); color: var(--gray-700); line-height: 1.8; }
.footer-col h5 { font-size: var(--text-xs); font-weight: 600; color: var(--brand-900); letter-spacing: 0.06em; margin: 0 0 16px; text-transform: uppercase; }
.footer-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.footer-col li a { color: var(--gray-600); }
.footer-col li a:hover { color: var(--brand-500); }
.footer-bottom { border-top: 1px solid var(--border-subtle); padding-top: 24px; display: flex; justify-content: space-between; font-size: var(--text-xs); color: var(--fg-subtle); }
@media (max-width: 1024px) {
.feat-hero-inner, .feat-block-inner, .feat-block.reverse .feat-block-inner, .cta-strip { grid-template-columns: 1fr; gap: 32px; }
.feat-block.reverse .feat-text, .feat-block.reverse .feat-visual { order: initial; }
.usecases-grid { grid-template-columns: 1fr 1fr; }
.footer-grid { grid-template-columns: 1fr 1fr; }
.feat-hero h1 { font-size: 36px; }
.composite { height: 480px; }
}
</style>
</head>
<body>
<nav class="topnav">
<div class="topnav-inner">
<a href="/" class="topnav-brand">
<img src="../assets/logo-full.svg" alt="岩美" />
</a>
<div class="topnav-links">
<a href="/#modules" class="active">产品</a>
<a href="/#pricing">价格</a>
<a href="/download.html">下载</a>
<a href="/docs.html">文档</a>
<a href="/#faq">支持</a>
</div>
<div class="topnav-cta" id="nav-cta"></div>
</div>
</nav>
<!-- ============== HERO ============== -->
<section class="feat-hero">
<div class="container feat-hero-inner">
<div>
<div class="feat-breadcrumb">
<a href="/">首页</a>
<i data-lucide="chevron-right" class="icon"></i>
<a href="/#modules">产品功能</a>
<i data-lucide="chevron-right" class="icon"></i>
<span style="color: var(--gray-900); font-weight: 500;">库存管理</span>
</div>
<p class="eyebrow">功能详情 · 库存管理</p>
<h1>实时库存,<br/>跨多仓追溯每一瓶酒。</h1>
<p class="lead">
从入库到售出,每一次库存变动都有记录、可追溯、可回放。多仓库统一管理、批次级追踪、账实差异自动核算 — 不止是库存表。
</p>
<div class="actions">
<a href="#" class="btn btn-primary btn-lg">免费试用 30 天</a>
<a href="/docs.html" class="btn btn-secondary btn-lg">
<i data-lucide="book-open" class="icon"></i>查看文档
</a>
</div>
<div class="quick-stats">
<div>
<div class="quick-stat-label">SKU 上限</div>
<div class="quick-stat-val">无限</div>
</div>
<div>
<div class="quick-stat-label">仓库支持</div>
<div class="quick-stat-val">多仓库</div>
</div>
<div>
<div class="quick-stat-label">流水保留</div>
<div class="quick-stat-val">永久</div>
</div>
</div>
</div>
<div class="composite">
<!-- Main inventory card -->
<div class="composite-card composite-main">
<div class="mc-head">
<div class="mc-title">库存列表 · A 仓</div>
<div class="mc-tabs">
<div class="mc-tab active">列表</div>
<div class="mc-tab">流水</div>
<div class="mc-tab">盘点</div>
</div>
</div>
<div class="mc-stats">
<div>
<div class="mc-stat-label">库存总量</div>
<div class="mc-stat-val">2,816<span class="delta">↑ 4.2%</span></div>
</div>
<div>
<div class="mc-stat-label">库存金额</div>
<div class="mc-stat-val">¥486K<span class="delta">↑ 2.8%</span></div>
</div>
<div>
<div class="mc-stat-label">预警 SKU</div>
<div class="mc-stat-val" style="color: var(--warning-500);">7</div>
</div>
</div>
<div class="mc-table">
<div class="mc-thead">
<div>SKU</div><div>商品</div><div>仓库</div><div>库存</div><div>批次</div><div>状态</div>
</div>
<div class="mc-trow">
<div class="sku">WT-501-006</div>
<div>茅台飞天 53°</div>
<div>A 仓</div>
<div>148</div>
<div>L-2026-04</div>
<div><span class="mc-pill ok">充足</span></div>
</div>
<div class="mc-trow">
<div class="sku">XJ-468-001</div>
<div>五粮液第八代</div>
<div>A 仓</div>
<div>92</div>
<div>L-2026-03</div>
<div><span class="mc-pill ok">充足</span></div>
</div>
<div class="mc-trow">
<div class="sku">XJ-330-024</div>
<div>剑南春水晶剑</div>
<div>B 仓</div>
<div style="color: var(--warning-700); font-weight: 500;">12</div>
<div>L-2026-02</div>
<div><span class="mc-pill warn">偏低</span></div>
</div>
<div class="mc-trow">
<div class="sku">PJ-750-012</div>
<div>拉菲传奇波尔多</div>
<div>A 仓</div>
<div>64</div>
<div>L-2026-05</div>
<div><span class="mc-pill ok">充足</span></div>
</div>
<div class="mc-trow">
<div class="sku">PJ-700-008</div>
<div>轩尼诗 VSOP</div>
<div>B 仓</div>
<div style="color: var(--danger-700); font-weight: 500;">3</div>
<div>L-2026-01</div>
<div><span class="mc-pill low">告急</span></div>
</div>
</div>
</div>
<!-- Floating alert card -->
<div class="composite-card composite-secondary">
<div class="alert-card-title" style="display: flex; align-items: center; gap: 6px;">
<i data-lucide="bell" class="icon" style="width: 12px; height: 12px; color: var(--warning-500);"></i>
库存预警
</div>
<div class="alert-row danger">
<div class="name">轩尼诗 VSOP</div>
<div class="qty">仅 3 瓶</div>
</div>
<div class="alert-row">
<div class="name">剑南春水晶剑</div>
<div class="qty">12 瓶</div>
</div>
<div class="alert-row">
<div class="name">人头马 X.O</div>
<div class="qty">8 瓶</div>
</div>
<div style="text-align: right; margin-top: 8px; font-size: 11px;">
<a href="#" style="color: var(--brand-500);">查看全部 7 条 →</a>
</div>
</div>
<!-- Floating batch card -->
<div class="composite-card composite-tertiary">
<div class="batch-title">
<i data-lucide="layers" class="icon"></i>
批次追踪 · L-2026-05
</div>
<div class="batch-row">
<div class="lot">入库 04-28</div>
<div>初始 50 瓶</div>
<div class="meta">A 仓</div>
<div>+50</div>
</div>
<div class="batch-row">
<div class="lot">出库 05-12</div>
<div>客户 · 春和宴</div>
<div class="meta">8 瓶</div>
<div>-8</div>
</div>
<div class="batch-row">
<div class="lot">出库 05-19</div>
<div>客户 · 北辰大酒店</div>
<div class="meta">12 瓶</div>
<div>-12</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============== BLOCK 1: Real-time inventory ============== -->
<section class="feat-block">
<div class="container feat-block-inner">
<div class="feat-text">
<div class="feat-tag"><i data-lucide="layout-list" class="icon"></i>实时库存查询</div>
<h2>不止是库存表,是一个可筛选的工作面板</h2>
<p class="lead">
库存数据自动跟随入库、出库、盘点变动 — 每一次写入都是一次事务,不存在「待同步」状态。
</p>
<ul class="feat-bullets">
<li>
<i data-lucide="filter" class="icon"></i>
<div>
<strong>多维筛选与列控制</strong>
按仓库、商品系列、库存状态、批次任意组合筛选,列可隐藏或重排。
</div>
</li>
<li>
<i data-lucide="search" class="icon"></i>
<div>
<strong>模糊搜索与拼音匹配</strong>
支持商品名、SKU、拼音首字母混合搜索,与你输入"飞天"同等结果。
</div>
</li>
<li>
<i data-lucide="pencil-line" class="icon"></i>
<div>
<strong>行内编辑备注</strong>
点击「备注」列即可弹出编辑框,不必进入详情页改字段。
</div>
</li>
<li>
<i data-lucide="file-spreadsheet" class="icon"></i>
<div>
<strong>一键导出 Excel</strong>
筛选后的视图与数据一同导出,可直接发给会计、税务。
</div>
</li>
</ul>
</div>
<div class="feat-visual">
<div class="visual-card">
<div class="visual-card-head">
<div class="visual-card-title">库存列表 · 全部仓库</div>
<div class="visual-card-meta">共 2,816 瓶 · ¥486,290</div>
</div>
<div class="inv-table">
<div class="inv-table-row head">
<div>SKU</div><div>商品名称 / 规格</div><div>仓库</div><div>库存</div><div>金额</div><div>状态</div>
</div>
<div class="inv-table-row">
<div class="sku">WT-501-006</div>
<div class="name">茅台飞天 53°<small>500ml×6 · L-2026-04</small></div>
<div>A 仓</div>
<div>148</div>
<div>¥298,400</div>
<div><span class="mc-pill ok">充足</span></div>
</div>
<div class="inv-table-row">
<div class="sku">XJ-468-001</div>
<div class="name">五粮液第八代 52°<small>500ml · L-2026-03</small></div>
<div>A 仓</div>
<div>92</div>
<div>¥92,920</div>
<div><span class="mc-pill ok">充足</span></div>
</div>
<div class="inv-table-row">
<div class="sku">XJ-330-024</div>
<div class="name">剑南春水晶剑 52°<small>500ml×6 · L-2026-02</small></div>
<div>B 仓</div>
<div style="color: var(--warning-700); font-weight: 500;">12</div>
<div>¥4,560</div>
<div><span class="mc-pill warn">偏低</span></div>
</div>
<div class="inv-table-row">
<div class="sku">PJ-750-012</div>
<div class="name">拉菲传奇波尔多<small>750ml · L-2026-05</small></div>
<div>A 仓</div>
<div>64</div>
<div>¥18,560</div>
<div><span class="mc-pill ok">充足</span></div>
</div>
<div class="inv-table-row">
<div class="sku">PJ-700-008</div>
<div class="name">轩尼诗 VSOP<small>700ml · L-2026-01</small></div>
<div>B 仓</div>
<div style="color: var(--danger-700); font-weight: 500;">3</div>
<div>¥1,770</div>
<div><span class="mc-pill low">告急</span></div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============== BLOCK 2: Batch tracking ============== -->
<section class="feat-block reverse">
<div class="container feat-block-inner">
<div class="feat-text">
<div class="feat-tag"><i data-lucide="layers" class="icon"></i>批次追踪</div>
<h2>每一批货的命运,<br/>都可以回放给你看</h2>
<p class="lead">
每张审批通过的入库单都会自动形成一个独立批次,可追踪其后续被谁出库、剩余多少、还在哪个仓库。
</p>
<ul class="feat-bullets">
<li>
<i data-lucide="git-branch" class="icon"></i>
<div>
<strong>批次自动生成</strong>
入库审批通过即建立批次,无需手动维护。
</div>
</li>
<li>
<i data-lucide="map-pin" class="icon"></i>
<div>
<strong>逐瓶溯源</strong>
出库时按"先进先出"自动从最早批次扣减,留下完整的批次→客户对应关系。
</div>
</li>
<li>
<i data-lucide="alert-circle" class="icon"></i>
<div>
<strong>过期预警</strong>
按生产日期 + 保质期推算,临近到期前自动标记。
</div>
</li>
<li>
<i data-lucide="qr-code" class="icon"></i>
<div>
<strong>标签二维码</strong>
每个批次都可打印含二维码的标签,扫码即查批次详情。
</div>
</li>
</ul>
</div>
<div class="feat-visual">
<div class="batch-journey">
<div class="batch-journey-head">
<div class="bj-meta-main">
<div class="bj-lot">L-2026-05</div>
<div class="bj-product">茅台飞天 53°<small>500ml×6 · A 仓</small></div>
</div>
<div class="bj-totals">
<div class="bj-total-row">初始入库 <strong>50 瓶</strong></div>
<div class="bj-total-row">累计出库 <strong style="color: var(--accent-500);">20 瓶</strong></div>
<div class="bj-total-row">剩余 <strong style="color: var(--success-700);">30 瓶</strong></div>
</div>
</div>
<div class="bj-progress">
<div class="bj-progress-bar" style="width: 60%;"></div>
</div>
<div class="bj-progress-labels">
<span>已出库 60%</span>
<span>40% 库存</span>
</div>
<div class="bj-timeline">
<div class="bj-event stockin">
<div class="bj-event-dot"></div>
<div class="bj-event-date">2026-04-28</div>
<div class="bj-event-desc">入库 · 供应商 茅台经销华东<small>经办人:李建国</small></div>
<div class="bj-event-qty">+50</div>
<div class="bj-event-doc">RK0007</div>
</div>
<div class="bj-event stockout">
<div class="bj-event-dot"></div>
<div class="bj-event-date">2026-05-12</div>
<div class="bj-event-desc">出库 · 客户 春和宴酒楼<small>经办人:王芳</small></div>
<div class="bj-event-qty">8</div>
<div class="bj-event-doc">CK0034</div>
</div>
<div class="bj-event stockout">
<div class="bj-event-dot"></div>
<div class="bj-event-date">2026-05-19</div>
<div class="bj-event-desc">出库 · 客户 北辰大酒店<small>经办人:王芳</small></div>
<div class="bj-event-qty">12</div>
<div class="bj-event-doc">CK0041</div>
</div>
<div class="bj-event">
<div class="bj-event-dot"></div>
<div class="bj-event-date">— 当前 —</div>
<div class="bj-event-desc" style="color: var(--gray-900); font-weight: 500;">剩余 30 瓶<small>预计 6 月底前售完</small></div>
<div class="bj-event-qty" style="color: var(--brand-700);">30</div>
<div class="bj-event-doc"></div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============== BLOCK 3: Stocktake ============== -->
<section class="feat-block">
<div class="container feat-block-inner">
<div class="feat-text">
<div class="feat-tag"><i data-lucide="clipboard-check" class="icon"></i>全仓盘点</div>
<h2>账面 vs 实际,差异一目了然</h2>
<p class="lead">
逐 SKU 录入实盘数量,系统自动核算账实差异、损耗金额,并一键转为盘亏调整单。
</p>
<ul class="feat-bullets">
<li>
<i data-lucide="warehouse" class="icon"></i>
<div>
<strong>跨多仓库联动</strong>
v1.6.2 新增 — 一次盘点可同步多仓库,避免分仓时数据不一致。
</div>
</li>
<li>
<i data-lucide="calculator" class="icon"></i>
<div>
<strong>差异自动核算</strong>
实盘填好后立即显示账面、实际、差异数量与金额。
</div>
</li>
<li>
<i data-lucide="history" class="icon"></i>
<div>
<strong>历史盘点对比</strong>
可对比上一次盘点结果,识别长期偏差最大的 SKU。
</div>
</li>
</ul>
</div>
<div class="feat-visual">
<div class="stocktake-table">
<div class="st-summary">
<div class="st-summary-item">
<div class="label">盘点商品</div>
<div class="val">128</div>
</div>
<div class="st-summary-item">
<div class="label">账面合计</div>
<div class="val">2,816</div>
</div>
<div class="st-summary-item">
<div class="label">实际合计</div>
<div class="val">2,808</div>
</div>
<div class="st-summary-item">
<div class="label">损耗金额</div>
<div class="val neg">−¥6,840</div>
</div>
</div>
<div class="st-row head">
<div>商品</div><div>账面</div><div>实际</div><div>差异</div><div>损耗</div>
</div>
<div class="st-row">
<div style="text-align: left;">茅台飞天 53° · 500ml×6</div>
<div>148</div>
<div>148</div>
<div><span class="diff-pill zero">0</span></div>
<div></div>
</div>
<div class="st-row">
<div style="text-align: left;">五粮液第八代 52° · 500ml</div>
<div>92</div>
<div>90</div>
<div><span class="diff-pill neg">2</span></div>
<div style="color: var(--danger-700);">−¥2,020</div>
</div>
<div class="st-row">
<div style="text-align: left;">剑南春水晶剑 52° · 500ml×6</div>
<div>12</div>
<div>12</div>
<div><span class="diff-pill zero">0</span></div>
<div></div>
</div>
<div class="st-row">
<div style="text-align: left;">拉菲传奇波尔多 · 750ml</div>
<div>64</div>
<div>60</div>
<div><span class="diff-pill neg">4</span></div>
<div style="color: var(--danger-700);">−¥1,160</div>
</div>
<div class="st-row">
<div style="text-align: left;">轩尼诗 VSOP · 700ml</div>
<div>3</div>
<div>3</div>
<div><span class="diff-pill zero">0</span></div>
<div></div>
</div>
<div class="st-row">
<div style="text-align: left;">人头马 X.O · 700ml</div>
<div>40</div>
<div>38</div>
<div><span class="diff-pill neg">2</span></div>
<div style="color: var(--danger-700);">−¥3,660</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============== BLOCK 4: Inventory logs ============== -->
<section class="feat-block reverse">
<div class="container feat-block-inner">
<div class="feat-text">
<div class="feat-tag"><i data-lucide="scroll-text" class="icon"></i>库存流水审计</div>
<h2>谁动了我的库存?<br/>每一次都查得清楚</h2>
<p class="lead">
所有库存变动都会自动写入流水表,包括入库、出库、盘点调整、单据红冲,附带时间戳与经办人。
</p>
<ul class="feat-bullets">
<li>
<i data-lucide="filter" class="icon"></i>
<div>
<strong>按类型 / 时间 / SKU 任意筛选</strong>
排查异常时可秒级定位。
</div>
</li>
<li>
<i data-lucide="link" class="icon"></i>
<div>
<strong>关联原单据</strong>
每条流水都关联到对应入库单 / 出库单 / 盘点单,一键跳转。
</div>
</li>
<li>
<i data-lucide="hard-drive" class="icon"></i>
<div>
<strong>永久保留</strong>
流水数据永不自动清除,满足审计与合规要求。
</div>
</li>
</ul>
</div>
<div class="feat-visual">
<div class="log-card">
<div class="log-toolbar">
<span class="log-filter-pill active">全部类型</span>
<span class="log-filter-pill"><i data-lucide="plus" class="icon"></i>入库</span>
<span class="log-filter-pill"><i data-lucide="minus" class="icon"></i>出库</span>
<span class="log-filter-pill"><i data-lucide="clipboard" class="icon"></i>盘点</span>
<span style="margin-left: auto;">本月 · 共 1,284 条</span>
</div>
<div class="log-row">
<div class="log-time">05-23 14:32</div>
<div><span class="log-type-pill in">入库</span></div>
<div class="log-desc">茅台飞天 53° · 500ml×6<small>RK20260523000007 · A 仓</small></div>
<div class="log-qty in">+4</div>
<div class="log-op">李建国</div>
</div>
<div class="log-row">
<div class="log-time">05-23 11:48</div>
<div><span class="log-type-pill out">出库</span></div>
<div class="log-desc">五粮液第八代 52°<small>CK20260523000012 · 客户 春和宴</small></div>
<div class="log-qty out">6</div>
<div class="log-op">王芳</div>
</div>
<div class="log-row">
<div class="log-time">05-23 10:15</div>
<div><span class="log-type-pill check">盘点</span></div>
<div class="log-desc">拉菲传奇波尔多<small>PD20260523001 · 账实差异</small></div>
<div class="log-qty out">2</div>
<div class="log-op">张磊</div>
</div>
<div class="log-row">
<div class="log-time">05-22 17:20</div>
<div><span class="log-type-pill out">出库</span></div>
<div class="log-desc">人头马 X.O · 700ml<small>CK20260522000008 · 客户 北辰</small></div>
<div class="log-qty out">2</div>
<div class="log-op">王芳</div>
</div>
<div class="log-row">
<div class="log-time">05-22 14:08</div>
<div><span class="log-type-pill in">入库</span></div>
<div class="log-desc">轩尼诗 VSOP · 700ml<small>RK20260522000005 · B 仓</small></div>
<div class="log-qty in">+24</div>
<div class="log-op">李建国</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============== BLOCK 5: Alerts ============== -->
<section class="feat-block">
<div class="container feat-block-inner">
<div class="feat-text">
<div class="feat-tag"><i data-lucide="bell" class="icon"></i>库存预警</div>
<h2>该补货之前,<br/>系统已经替你看见了</h2>
<p class="lead">
每个 SKU 都可单独设置安全库存阈值,触发即在 Web 与移动端同步推送,永远不会错过补货时机。
</p>
<ul class="feat-bullets">
<li>
<i data-lucide="sliders-horizontal" class="icon"></i>
<div>
<strong>按 SKU 灵活配置</strong>
热销商品阈值高,冷门商品阈值低 — 不需要一刀切。
</div>
</li>
<li>
<i data-lucide="bell-ring" class="icon"></i>
<div>
<strong>多渠道通知</strong>
Web 顶栏、移动 App 推送、可选邮件 / 短信通知。
</div>
</li>
<li>
<i data-lucide="trending-up" class="icon"></i>
<div>
<strong>智能补货建议</strong>
基于近 30 天销售速率 × 补货周期,给出建议补货量。<small style="color: var(--brand-500);">v1.7 Beta</small>
</div>
</li>
</ul>
</div>
<div class="feat-visual">
<div class="alert-config-card">
<h4>预警阈值 · 茅台飞天 53°</h4>
<p class="sub">当库存低于阈值时,自动推送给指定操作员。</p>
<div class="threshold-bar">
<div class="threshold-track"></div>
<div class="threshold-marker" style="left: 30%;"></div>
<div class="threshold-tick" style="left: 0%;">0</div>
<div class="threshold-tick" style="left: 18%;">20</div>
<div class="threshold-tick" style="left: 42%;">50</div>
<div class="threshold-tick" style="left: 100%;">200</div>
<div class="threshold-label" style="left: 9%; color: var(--danger-700);">告急</div>
<div class="threshold-label" style="left: 30%; color: var(--warning-700);">偏低</div>
<div class="threshold-label" style="left: 70%; color: var(--success-700);">充足</div>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; margin: 16px 0 8px;">
<span style="font-size: 13px; color: var(--gray-700);">当前阈值</span>
<span style="font-family: var(--font-mono); font-size: 18px; font-weight: 600; color: var(--brand-700);">35 瓶</span>
</div>
<div class="alert-rules">
<div class="alert-rule">
<div>低于 <strong>50 瓶</strong> · 推送给 <strong>张磊(仓储)</strong></div>
<div class="switch"></div>
</div>
<div class="alert-rule">
<div>低于 <strong>20 瓶</strong> · 短信通知 <strong>李建国(采购)</strong></div>
<div class="switch"></div>
</div>
<div class="alert-rule">
<div>临近过期 <strong>30 天</strong> · 邮件提醒</div>
<div class="switch off"></div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============== Use cases ============== -->
<section class="section" style="background: var(--bg-surface); border-bottom: 1px solid var(--border-subtle);">
<div class="container">
<p class="eyebrow">典型场景</p>
<h2 style="font-size: 36px; font-weight: 600; color: var(--brand-900); margin: 0 0 12px; letter-spacing: var(--tracking-cn-display);">
库存管理,落到实际操作里是什么样
</h2>
<p style="font-size: var(--text-lg); color: var(--fg-muted); max-width: 640px; margin: 0;">
三个常见门店场景,看库存管理如何省下你每天的时间。
</p>
<div class="usecases-grid">
<div class="usecase-card">
<i data-lucide="package-search" class="icon"></i>
<h4>客户来取货前,先看一眼批次</h4>
<p>客户要 12 瓶飞天,先在批次追踪里看哪一批快到期;优先发出旧批次,新批次留着。</p>
</div>
<div class="usecase-card">
<i data-lucide="calendar-check-2" class="icon"></i>
<h4>月底盘点,2 小时变 30 分钟</h4>
<p>用移动端扫码逐瓶录入,系统对比账面 → 实时显示差异。损耗自动转入应付,不用再算。</p>
</div>
<div class="usecase-card">
<i data-lucide="file-check-2" class="icon"></i>
<h4>财务来问"这瓶怎么少了",3 秒回答</h4>
<p>打开库存流水,按 SKU 筛选,全部入库、出库、盘点变动一目了然,每条都关联到原始单据。</p>
</div>
</div>
</div>
</section>
<!-- ============== Final CTA ============== -->
<section>
<div class="container" style="padding-top: 80px;">
<div class="cta-strip">
<div>
<h2>试试看你今天的库存有几瓶。</h2>
<p>30 天免费试用,无需绑定支付。所有数据云端实时备份,可随时导出。</p>
</div>
<div class="cta-strip-actions">
<a href="#" class="btn btn-primary btn-lg">
免费开通试用<i data-lucide="arrow-right" class="icon"></i>
</a>
<a href="/features/approval.html" class="btn btn-secondary btn-lg">
下一个功能:审核流 →
</a>
</div>
</div>
</div>
</section>
<!-- ============== Footer ============== -->
<footer>
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<img src="../assets/logo-full.svg" alt="岩美" />
<p>为酒行与酒店设计的库存、审核、财务一体化管理平台。</p>
<div class="footer-contact">
<div>support@yanmei.app</div>
<div>400-880-8888</div>
</div>
</div>
<div class="footer-col">
<h5>产品</h5>
<ul>
<li><a href="/#modules">核心模块</a></li>
<li><a href="/features/inventory.html">库存管理</a></li>
<li><a href="/features/approval.html">审核流</a></li>
<li><a href="/#pricing">价格方案</a></li>
<li><a href="/download.html">下载客户端</a></li>
</ul>
</div>
<div class="footer-col">
<h5>资源</h5>
<ul>
<li><a href="/docs.html">使用手册</a></li>
<li><a href="#">API 文档</a></li>
<li><a href="#">视频教程</a></li>
<li><a href="#">数据导入模板</a></li>
</ul>
</div>
<div class="footer-col">
<h5>客户支持</h5>
<ul>
<li><a href="/#faq">常见问题</a></li>
<li><a href="#">提交工单</a></li>
<li><a href="#">技术支持</a></li>
<li><a href="#">服务等级</a></li>
</ul>
</div>
<div class="footer-col">
<h5>公司</h5>
<ul>
<li><a href="#">关于岩美</a></li>
<li><a href="#">客户案例</a></li>
<li><a href="#">招贤纳士</a></li>
<li><a href="#">联系我们</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div>© 2026 岩美科技 · 保留所有权利</div>
<div>沪 ICP 备 2026000000 号 · 沪公网安备 31010000000000 号</div>
</div>
</div>
</footer>
<script>
function getAuthUser() {
var token = localStorage.getItem('flutter.access_token');
var username = localStorage.getItem('flutter.username');
var realName = localStorage.getItem('flutter.real_name') || '';
var role = localStorage.getItem('flutter.role') || '';
var shopNo = localStorage.getItem('flutter.shop_no') || '';
if (!token || !username) return null;
return { username: username, realName: realName, role: role, shopNo: shopNo };
}
function doLogout() {
['access_token','refresh_token','username','real_name','shop_no','shop_id','role']
.forEach(function(k) { localStorage.removeItem('flutter.' + k); });
location.reload();
}
function toggleUserMenu() {
var el = document.getElementById('userDropdown');
if (el) el.classList.toggle('open');
}
function renderNav() {
var cta = document.getElementById('nav-cta');
if (!cta) return;
var user = getAuthUser();
if (user) {
var initial = (user.realName || user.username).charAt(0).toUpperCase();
var displayName = user.realName || user.username;
var roleLabel = { admin: '管理员', operator: '操作员', readonly: '只读', superadmin: '超管' }[user.role] || user.role;
cta.innerHTML =
'<div class="nav-user">' +
'<button class="nav-user-btn" onclick="toggleUserMenu()">' +
'<div class="nav-avatar">' + initial + '</div>' +
'<span>' + displayName + '</span>' +
'<i data-lucide="chevron-down" class="icon"></i>' +
'</button>' +
'<div class="nav-dropdown" id="userDropdown">' +
'<div class="nav-dropdown-info">' +
'<div class="nav-dropdown-name">' + displayName + '</div>' +
'<div class="nav-dropdown-role">' + roleLabel + (user.shopNo ? ' · ' + user.shopNo : '') + '</div>' +
'</div>' +
'<a href="/app"><i data-lucide="layout-dashboard" class="icon"></i>进入系统</a>' +
'<button class="logout" onclick="doLogout()"><i data-lucide="log-out" class="icon"></i>退出登录</button>' +
'</div>' +
'</div>';
} else {
cta.innerHTML =
'<a href="/app/login" class="btn btn-ghost">登录</a>' +
'<a href="/app/register" class="btn btn-primary">免费试用</a>';
}
if (window.lucide) lucide.createIcons();
}
document.addEventListener('click', function(e) {
var dropdown = document.getElementById('userDropdown');
if (dropdown && dropdown.classList.contains('open')) {
var userEl = dropdown.closest('.nav-user');
if (userEl && !userEl.contains(e.target)) dropdown.classList.remove('open');
}
});
document.addEventListener('DOMContentLoaded', function() {
if (window.lucide) lucide.createIcons();
renderNav();
});
</script>
</body>
</html>