Files
youzan-datahub/dashboard-ui/index.html

245 lines
15 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>
<!-- Google Fonts for Apple-like Typography -->
<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=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
<!-- ECharts -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
</head>
<body>
<div class="app-container">
<!-- Sidebar Navigation -->
<aside class="sidebar">
<div class="logo">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
<polyline points="2 17 12 22 22 17"></polyline>
<polyline points="2 12 12 17 22 12"></polyline>
</svg>
<span>DataHub Core</span>
</div>
<nav class="nav-menu">
<a href="#" class="nav-item active">大盘总览</a>
<a href="#" class="nav-item">商品洞察</a>
<a href="#" class="nav-item">会员画像</a>
<a href="#" class="nav-item">订货建议</a>
<a href="#" class="nav-item">运维管理</a>
</nav>
</aside>
<!-- Main Content -->
<main class="main-content">
<header class="top-nav">
<div class="page-title-row">
<h1 id="page-title">经营数据大盘概览</h1>
<span id="data-cutoff-badge" class="data-cutoff-badge">计算数据截止至 —</span>
</div>
<div class="header-actions">
<button class="btn-refresh" onclick="fetchData()">刷新数据</button>
<div class="user-profile">
<img src="https://ui-avatars.com/api/?name=Admin&background=000&color=fff" alt="Admin">
</div>
</div>
</header>
<!-- Page 1: 大盘总览 -->
<div id="page-overview" class="page-section active">
<div class="dashboard-grid">
<!-- Overview Cards -->
<div class="metrics-row">
<div class="glass-card metric-card">
<h3>过去14天总营收 <span class="info-icon" data-tooltip="SUM(实付金额), 仅统计 TRADE_SUCCESS 状态的订单, 时间范围: 近14天按 pay_time 筛选"></span></h3>
<div class="value" id="revenue-val">¥0.00</div>
<div class="trend positive"><span></span> 实时</div>
</div>
<div class="glass-card metric-card">
<h3>过去14天订单数 <span class="info-icon" data-tooltip="COUNT(DISTINCT tid), 近14天内有 pay_time 的不重复订单号数量"></span></h3>
<div class="value" id="orders-val">0</div>
<div class="trend positive"><span></span> 实时</div>
</div>
<div class="glass-card metric-card">
<h3>平均客单价 (ATV) <span class="info-icon" data-tooltip="= 过去14天总营收 ÷ 过去14天订单数, 每笔订单的平均消费金额"></span></h3>
<div class="value" id="atv-val">¥0.00</div>
<div class="trend neutral">稳定</div>
</div>
<div class="glass-card metric-card">
<h3>过去14天退款额 <span class="info-icon" data-tooltip="SUM(refund_fee), 近14天内创建的退款单退款金额总计"></span></h3>
<div class="value" id="refund-val">¥0.00</div>
<div class="trend negative"><span></span> 风控监测中</div>
</div>
</div>
<!-- Charts Area -->
<div class="charts-row">
<div class="glass-card chart-container">
<div class="chart-header">
<h2>14天营收曲线 (Sales Trend) <span class="info-icon" data-tooltip="X轴=日期, 蓝线=当日SUM(payment), 红虚线=当日COUNT(DISTINCT tid), 按 pay_time 分组"></span></h2>
</div>
<div id="trendChart" style="width: 100%; height: 350px;"></div>
</div>
</div>
</div>
</div>
<!-- Page 2: 商品洞察 -->
<div id="page-product" class="page-section" style="display: none;">
<div class="dashboard-grid">
<div class="glass-card chart-container">
<div class="chart-header">
<h2>商品30天复购率与波士顿矩阵 <span class="info-icon" data-tooltip="每日洞察计算任务生成, 统计近30天各商品的购买/复购人数"></span></h2>
</div>
<div class="table-responsive">
<table class="data-table" id="repurchase-table">
<thead>
<tr>
<th>商品名称</th>
<th>30天购买人数 <span class="info-icon info-icon-sm" data-tooltip="COUNT(DISTINCT yz_open_id), 近30天购买过该商品的不重复客户数"></span></th>
<th>30天复购人数 <span class="info-icon info-icon-sm" data-tooltip="近30天内购买该商品≥2次的客户数"></span></th>
<th>复购率 <span class="info-icon info-icon-sm" data-tooltip="= 复购人数 ÷ 购买人数 × 100%"></span></th>
<th>波士顿矩阵打标 <span class="info-icon info-icon-sm" data-tooltip="购买人数高+复购率高=核心引流爆款; 购买人数高+复购率低=体验差需淘汰; 购买人数低+复购率高=小众潜力款; 其他=长尾观测品"></span></th>
</tr>
</thead>
<tbody>
<tr><td colspan="5" class="text-center">加载中...</td></tr>
</tbody>
</table>
</div>
</div>
<div class="glass-card chart-container">
<div class="chart-header">
<h2>购物篮热门连带趋势 (Apriori Top20) <span class="info-icon" data-tooltip="Apriori关联规则挖掘, 基于近30天同一订单(tid)内共同出现的商品对"></span></h2>
</div>
<div class="table-responsive">
<table class="data-table" id="basket-table">
<thead>
<tr>
<th>核心商品 A</th>
<th>连带商品 B</th>
<th>共同出现订单数 <span class="info-icon info-icon-sm" data-tooltip="在同一笔订单中同时购买A和B的订单数"></span></th>
<th>搭配置信度 <span class="info-icon info-icon-sm" data-tooltip="= 同时购买A和B的订单数 ÷ 购买A的订单数 × 100%, 即买了A的人有多大概率也买B"></span></th>
</tr>
</thead>
<tbody>
<tr><td colspan="4" class="text-center">加载中...</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Page 3: 会员画像 -->
<div id="page-customer" class="page-section" style="display: none;">
<div class="dashboard-grid">
<div class="metrics-row" id="rfm-cards">
<!-- RFM Cards rendered via JS -->
</div>
<div class="glass-card chart-container">
<div class="chart-header">
<h2>全域会员标签分布 <span class="info-icon" data-tooltip="基于 RFM 模型对客户分群打标后, 各标签的人数分布饼图"></span></h2>
</div>
<div id="tagChart" style="width: 100%; height: 350px;"></div>
</div>
</div>
</div>
<!-- Page 4: 订货建议 -->
<div id="page-advice" class="page-section" style="display: none;">
<div class="glass-card chart-container">
<div class="chart-header">
<h2>次日智能安全备货单 (过去14天流速推断) <span class="info-icon" data-tooltip="基于近14天每日平均销量(日均流速), 计算3天安全备货量"></span></h2>
</div>
<div class="table-responsive">
<table class="data-table" id="advice-table">
<thead>
<tr>
<th>商品名称</th>
<th>14天总销量 <span class="info-icon info-icon-sm" data-tooltip="近14天该商品的订单明细数量合计 (件数)"></span></th>
<th>日均流速 <span class="info-icon info-icon-sm" data-tooltip="= 14天总销量 ÷ 14, 平均每天销售几件"></span></th>
<th>建议安全补货量 (3天量) <span class="info-icon info-icon-sm" data-tooltip="= CEIL(日均流速 × 3), 向上取整确保安全库存"></span></th>
</tr>
</thead>
<tbody>
<tr><td colspan="4" class="text-center">加载中...</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- Page 5: 运维管理 -->
<div id="page-ops" class="page-section" style="display: none;">
<div class="dashboard-grid">
<div class="glass-card chart-container">
<div class="chart-header">
<h2>数据同步 & 洞察计算 手动触发</h2>
</div>
<p style="color: #86868b; margin: 0 0 1.5rem 0; font-size: 0.9rem;">
以下操作与每日定时任务相同,点击后将实时执行并返回结果。执行耗时视数据量而定,请耐心等待。
</p>
<!-- 日期选择器: 订单/退款同步可选起始日期 -->
<div class="ops-date-row">
<label for="ops-from-date" class="ops-date-label">指定起始日期</label>
<input type="date" id="ops-from-date" class="ops-date-input" />
<span class="ops-date-hint">留空 = 自动检测缺口 (智能模式)</span>
</div>
<div class="ops-grid">
<button class="ops-btn" onclick="triggerOps('sync-orders', this)">
<span class="ops-icon">📦</span>
<span class="ops-label">订单同步</span>
<span class="ops-desc">智能增量 / 指定日期</span>
</button>
<button class="ops-btn" onclick="triggerOps('sync-refunds', this)">
<span class="ops-icon">💰</span>
<span class="ops-label">退款同步</span>
<span class="ops-desc">智能增量 / 指定日期</span>
</button>
<button class="ops-btn" onclick="triggerOps('sync-items', this)">
<span class="ops-icon">🍱</span>
<span class="ops-label">商品同步</span>
<span class="ops-desc">全量商品目录</span>
</button>
<button class="ops-btn" onclick="triggerOps('sync-stores', this)">
<span class="ops-icon">🏪</span>
<span class="ops-label">门店同步</span>
<span class="ops-desc">门店与网点</span>
</button>
<button class="ops-btn" onclick="triggerOps('sync-inventory', this)">
<span class="ops-icon">📊</span>
<span class="ops-label">库存快照</span>
<span class="ops-desc">各门店库存</span>
</button>
<button class="ops-btn" onclick="triggerOps('sync-customers', this)">
<span class="ops-icon">👥</span>
<span class="ops-label">客户聚合</span>
<span class="ops-desc">订单驱动聚合</span>
</button>
<button class="ops-btn ops-btn-accent" onclick="triggerOps('compute-insights', this)">
<span class="ops-icon">🧠</span>
<span class="ops-label">洞察计算</span>
<span class="ops-desc">RFM+复购+购物篮</span>
</button>
</div>
<div class="ops-log-container">
<h3 style="margin: 0 0 0.5rem 0;">执行日志</h3>
<div id="ops-log" class="ops-log"><span class="log-entry log-placeholder"><span class="log-time"></span>等待操作...</span></div>
</div>
</div>
</div>
</div>
</main>
</div>
<script src="app.js"></script>
</body>
</html>