Files
TakeoutSaaS.Prototypes/pages/stat-customer.html

282 lines
18 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.
<!-- 客户分析 — stat-customer.html -->
<style>
/* ---- page-private: sc- prefix ---- */
.sc-page { display:flex; flex-direction:column; gap:14px; }
/* 顶部统计卡片 */
.sc-kpi-row { display:grid; grid-template-columns:repeat(4,1fr); gap:14px; }
.sc-kpi {
background:#fff; border-radius:var(--g-radius); border:1px solid var(--g-border);
padding:18px 20px; box-shadow:var(--g-shadow-sm); transition:box-shadow var(--g-transition);
}
.sc-kpi:hover { box-shadow:var(--g-shadow-md); }
.sc-kpi-label { font-size:13px; color:var(--g-text-secondary); margin-bottom:8px; display:flex; align-items:center; gap:6px; }
.sc-kpi-label i { width:16px; height:16px; }
.sc-kpi-val { font-size:28px; font-weight:700; color:var(--g-text); line-height:1.2; }
.sc-kpi-hint { font-size:11px; color:var(--g-text-muted); margin-top:6px; display:flex; align-items:center; gap:4px; }
.sc-kpi-hint .up { color:var(--g-success); font-weight:600; }
.sc-kpi-hint .down { color:var(--g-danger); font-weight:600; }
/* 分段Tab */
.sc-seg-wrap { background:#fff; border-radius:var(--g-radius); border:1px solid var(--g-border); padding:14px 20px 0; box-shadow:var(--g-shadow-sm); }
.sc-tab-panel { display:none; padding:16px 0 20px; }
.sc-tab-panel.active { display:block; }
/* Section 标题 */
.sc-section-hd { font-size:15px; font-weight:600; color:var(--g-text); padding-left:10px; border-left:3px solid var(--primary); margin-bottom:16px; }
/* Tab1: 柱状图 */
.sc-chart-wrap { background:#fafafa; border-radius:var(--g-radius); padding:20px; margin-bottom:20px; }
.sc-bar-chart { display:flex; align-items:flex-end; gap:16px; height:220px; padding:10px 0; }
.sc-bar-group { flex:1; display:flex; flex-direction:column; align-items:center; gap:6px; }
.sc-bar-pair { display:flex; gap:4px; align-items:flex-end; height:180px; }
.sc-bar { width:24px; border-radius:4px 4px 0 0; transition:height 0.5s cubic-bezier(.2,0,0,1); position:relative; cursor:pointer; }
.sc-bar:hover { opacity:0.85; }
.sc-bar.new-c { background:linear-gradient(180deg,#1890ff,#69c0ff); }
.sc-bar.ret-c { background:linear-gradient(180deg,#52c41a,#95de64); }
.sc-bar-num { position:absolute; top:-18px; left:50%; transform:translateX(-50%); font-size:10px; color:var(--g-text-secondary); white-space:nowrap; font-weight:600; }
.sc-bar-label { font-size:12px; color:var(--g-text-muted); }
.sc-legend { display:flex; gap:16px; justify-content:center; margin-top:10px; font-size:12px; color:var(--g-text-muted); }
.sc-legend-dot { display:inline-block; width:10px; height:10px; border-radius:2px; margin-right:4px; vertical-align:middle; }
/* Tab2: RFM */
.sc-rfm-info {
background:color-mix(in srgb, var(--primary) 6%, #fff); border:1px solid color-mix(in srgb, var(--primary) 15%, #fff);
border-radius:var(--g-radius-sm); padding:10px 14px; font-size:12px; color:var(--g-text-secondary); margin-bottom:16px;
display:flex; align-items:center; gap:6px;
}
.sc-rfm-info i { width:16px; height:16px; color:var(--primary); flex-shrink:0; }
.sc-rfm-grid { display:grid; grid-template-columns:1fr 1fr 1fr; gap:14px; }
.sc-rfm-card {
border-radius:var(--g-radius); padding:18px; border:1px solid var(--g-border);
transition:box-shadow var(--g-transition); position:relative; overflow:hidden;
}
.sc-rfm-card:hover { box-shadow:var(--g-shadow-md); }
.sc-rfm-card::before { content:''; position:absolute; top:0; left:0; right:0; height:3px; }
.sc-rfm-card.green::before { background:var(--g-success); }
.sc-rfm-card.blue::before { background:var(--primary); }
.sc-rfm-card.orange::before { background:var(--g-warning); }
.sc-rfm-card.red::before { background:var(--g-danger); }
.sc-rfm-card.cyan::before { background:#13c2c2; }
.sc-rfm-card.gray::before { background:#bfbfbf; }
.sc-rfm-name { font-size:14px; font-weight:600; color:var(--g-text); margin-bottom:4px; }
.sc-rfm-desc { font-size:11px; color:var(--g-text-muted); margin-bottom:10px; }
.sc-rfm-num { font-size:22px; font-weight:700; color:var(--g-text); }
.sc-rfm-pct { font-size:12px; color:var(--g-text-secondary); margin-left:6px; }
.sc-rfm-link { font-size:12px; color:var(--primary); cursor:pointer; margin-top:10px; display:inline-block; }
.sc-rfm-link:hover { text-decoration:underline; }
/* Tab3: 流失预警 */
.sc-warn-row { display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin-bottom:16px; }
.sc-warn-card {
background:#fff; border-radius:var(--g-radius); border:1px solid var(--g-border);
padding:16px 18px; text-align:center; box-shadow:var(--g-shadow-sm);
}
.sc-warn-card-val { font-size:24px; font-weight:700; margin:6px 0 4px; }
.sc-warn-card-val.low { color:var(--g-warning); }
.sc-warn-card-val.mid { color:#fa541c; }
.sc-warn-card-val.high { color:var(--g-danger); }
.sc-warn-card-label { font-size:13px; color:var(--g-text-secondary); }
/* Tab4: 复购周期 - 横向柱状图 */
.sc-hbar-wrap { margin-bottom:20px; }
.sc-hbar-item { display:flex; align-items:center; gap:10px; margin-bottom:10px; }
.sc-hbar-label { width:70px; font-size:13px; color:var(--g-text-secondary); text-align:right; flex-shrink:0; }
.sc-hbar-track { flex:1; height:24px; background:#f5f5f5; border-radius:4px; overflow:hidden; position:relative; }
.sc-hbar-fill { height:100%; border-radius:4px; background:linear-gradient(90deg,#1890ff,#69c0ff); transition:width 0.6s cubic-bezier(.2,0,0,1); display:flex; align-items:center; padding-left:8px; }
.sc-hbar-fill span { font-size:11px; color:#fff; font-weight:600; white-space:nowrap; }
.sc-hbar-val { width:90px; font-size:12px; color:var(--g-text-muted); flex-shrink:0; }
.sc-hbar-desc { font-size:12px; color:var(--g-text-muted); margin-bottom:16px; padding:8px 12px; background:#fafafa; border-radius:var(--g-radius-sm); }
</style>
<div class="sc-page">
<!-- 顶部统计卡片 -->
<div class="sc-kpi-row">
<div class="sc-kpi">
<div class="sc-kpi-label"><i data-lucide="users"></i>累计客户</div>
<div class="sc-kpi-val">2,860</div>
<div class="sc-kpi-hint">较上月 +210</div>
</div>
<div class="sc-kpi">
<div class="sc-kpi-label"><i data-lucide="user-plus"></i>本月新客</div>
<div class="sc-kpi-val">186</div>
<div class="sc-kpi-hint">环比 <span class="up">+12%</span></div>
</div>
<div class="sc-kpi">
<div class="sc-kpi-label"><i data-lucide="repeat"></i>回头客占比</div>
<div class="sc-kpi-val">42.5%</div>
<div class="sc-kpi-hint">环比 <span class="up">+3.2%</span></div>
</div>
<div class="sc-kpi">
<div class="sc-kpi-label"><i data-lucide="calendar-clock"></i>平均消费频次</div>
<div class="sc-kpi-val">2.8<span style="font-size:14px;font-weight:400;color:var(--g-text-muted);margin-left:2px">次/月</span></div>
<div class="sc-kpi-hint">环比 <span class="up">+0.3</span></div>
</div>
</div>
<!-- 分段Tab -->
<div class="sc-seg-wrap">
<div class="g-seg" style="max-width:420px;">
<div class="g-seg-item active" onclick="switchScTab(this,'overview')">客户概览</div>
<div class="g-seg-item" onclick="switchScTab(this,'rfm')">RFM分层</div>
<div class="g-seg-item" onclick="switchScTab(this,'churn')">流失预警</div>
<div class="g-seg-item" onclick="switchScTab(this,'repurchase')">复购周期</div>
</div>
<!-- Tab1: 客户概览 -->
<div id="scTabOverview" class="sc-tab-panel active">
<div class="sc-section-hd">新客 vs 回头客趋势近6个月</div>
<div class="sc-chart-wrap">
<div class="sc-bar-chart">
<div class="sc-bar-group"><div class="sc-bar-pair"><div class="sc-bar new-c" style="height:40%;"><span class="sc-bar-num">120</span></div><div class="sc-bar ret-c" style="height:55%;"><span class="sc-bar-num">165</span></div></div><span class="sc-bar-label">8月</span></div>
<div class="sc-bar-group"><div class="sc-bar-pair"><div class="sc-bar new-c" style="height:48%;"><span class="sc-bar-num">145</span></div><div class="sc-bar ret-c" style="height:52%;"><span class="sc-bar-num">156</span></div></div><span class="sc-bar-label">9月</span></div>
<div class="sc-bar-group"><div class="sc-bar-pair"><div class="sc-bar new-c" style="height:55%;"><span class="sc-bar-num">168</span></div><div class="sc-bar ret-c" style="height:60%;"><span class="sc-bar-num">180</span></div></div><span class="sc-bar-label">10月</span></div>
<div class="sc-bar-group"><div class="sc-bar-pair"><div class="sc-bar new-c" style="height:45%;"><span class="sc-bar-num">138</span></div><div class="sc-bar ret-c" style="height:65%;"><span class="sc-bar-num">195</span></div></div><span class="sc-bar-label">11月</span></div>
<div class="sc-bar-group"><div class="sc-bar-pair"><div class="sc-bar new-c" style="height:52%;"><span class="sc-bar-num">158</span></div><div class="sc-bar ret-c" style="height:70%;"><span class="sc-bar-num">210</span></div></div><span class="sc-bar-label">12月</span></div>
<div class="sc-bar-group"><div class="sc-bar-pair"><div class="sc-bar new-c" style="height:60%;"><span class="sc-bar-num">186</span></div><div class="sc-bar ret-c" style="height:72%;"><span class="sc-bar-num">218</span></div></div><span class="sc-bar-label">1月</span></div>
</div>
<div class="sc-legend">
<span><span class="sc-legend-dot" style="background:#1890ff;"></span>新客</span>
<span><span class="sc-legend-dot" style="background:#52c41a;"></span>回头客</span>
</div>
</div>
<div class="sc-section-hd">客单价分布</div>
<table class="g-table">
<thead><tr><th>价格区间</th><th>客户数</th><th>占比</th><th>累计占比</th></tr></thead>
<tbody>
<tr><td>0 - 20 元</td><td>286</td><td>10.0%</td><td>10.0%</td></tr>
<tr><td>20 - 40 元</td><td>915</td><td>32.0%</td><td>42.0%</td></tr>
<tr><td>40 - 60 元</td><td>743</td><td>26.0%</td><td>68.0%</td></tr>
<tr><td>60 - 80 元</td><td>486</td><td>17.0%</td><td>85.0%</td></tr>
<tr><td>80 - 100 元</td><td>258</td><td>9.0%</td><td>94.0%</td></tr>
<tr><td>100 元以上</td><td>172</td><td>6.0%</td><td>100.0%</td></tr>
</tbody>
</table>
</div>
<!-- Tab2: RFM分层 -->
<div id="scTabRfm" class="sc-tab-panel">
<div class="sc-section-hd">RFM 客户分层</div>
<div class="sc-rfm-info">
<i data-lucide="info"></i>
RFM 模型基于三个维度对客户进行分层最近消费时间Recency、消费频率Frequency、消费金额Monetary帮助识别高价值客户并制定差异化运营策略。
</div>
<div class="sc-rfm-grid">
<div class="sc-rfm-card green">
<div class="sc-rfm-name">重要价值客户</div>
<div class="sc-rfm-desc">R高 F高 M高</div>
<div><span class="sc-rfm-num">320</span><span class="sc-rfm-pct">人,占 11.2%</span></div>
<a class="sc-rfm-link">查看详情 &rarr;</a>
</div>
<div class="sc-rfm-card blue">
<div class="sc-rfm-name">重要发展客户</div>
<div class="sc-rfm-desc">R高 F低 M高</div>
<div><span class="sc-rfm-num">186</span><span class="sc-rfm-pct">人,占 6.5%</span></div>
<a class="sc-rfm-link">查看详情 &rarr;</a>
</div>
<div class="sc-rfm-card orange">
<div class="sc-rfm-name">重要保持客户</div>
<div class="sc-rfm-desc">R低 F高 M高</div>
<div><span class="sc-rfm-num">245</span><span class="sc-rfm-pct">人,占 8.6%</span></div>
<a class="sc-rfm-link">查看详情 &rarr;</a>
</div>
<div class="sc-rfm-card red">
<div class="sc-rfm-name">重要挽留客户</div>
<div class="sc-rfm-desc">R低 F低 M高</div>
<div><span class="sc-rfm-num">128</span><span class="sc-rfm-pct">人,占 4.5%</span></div>
<a class="sc-rfm-link">查看详情 &rarr;</a>
</div>
<div class="sc-rfm-card cyan">
<div class="sc-rfm-name">一般价值客户</div>
<div class="sc-rfm-desc">R高 F高 M低</div>
<div><span class="sc-rfm-num">580</span><span class="sc-rfm-pct">人,占 20.3%</span></div>
<a class="sc-rfm-link">查看详情 &rarr;</a>
</div>
<div class="sc-rfm-card gray">
<div class="sc-rfm-name">一般客户</div>
<div class="sc-rfm-desc">其他组合</div>
<div><span class="sc-rfm-num">1,401</span><span class="sc-rfm-pct">人,占 49.0%</span></div>
<a class="sc-rfm-link">查看详情 &rarr;</a>
</div>
</div>
</div>
<!-- Tab3: 流失预警 -->
<div id="scTabChurn" class="sc-tab-panel">
<div class="sc-section-hd">流失预警</div>
<div class="sc-warn-row">
<div class="sc-warn-card">
<div class="sc-warn-card-label">30天未消费</div>
<div class="sc-warn-card-val low">186</div>
<div style="font-size:11px;color:var(--g-text-muted);"></div>
</div>
<div class="sc-warn-card">
<div class="sc-warn-card-label">60天未消费</div>
<div class="sc-warn-card-val mid">95</div>
<div style="font-size:11px;color:var(--g-text-muted);"></div>
</div>
<div class="sc-warn-card">
<div class="sc-warn-card-label">90天+未消费</div>
<div class="sc-warn-card-val high">42</div>
<div style="font-size:11px;color:var(--g-text-muted);"></div>
</div>
</div>
<table class="g-table">
<thead>
<tr><th>客户名</th><th>手机号</th><th>最后消费时间</th><th>累计消费</th><th>未消费天数</th><th>流失风险</th><th>操作</th></tr>
</thead>
<tbody>
<tr><td>张*明</td><td>138****6721</td><td>2025-11-02</td><td>&yen;1,280</td><td>92</td><td><span class="g-tag g-tag-red"></span></td><td><a class="g-action">发券挽回</a></td></tr>
<tr><td>李*华</td><td>159****3348</td><td>2025-11-18</td><td>&yen;860</td><td>76</td><td><span class="g-tag g-tag-red"></span></td><td><a class="g-action">发券挽回</a></td></tr>
<tr><td>王*</td><td>136****9012</td><td>2025-12-05</td><td>&yen;2,150</td><td>59</td><td><span class="g-tag g-tag-orange"></span></td><td><a class="g-action">发券挽回</a></td></tr>
<tr><td>赵*丽</td><td>188****4567</td><td>2025-12-12</td><td>&yen;560</td><td>52</td><td><span class="g-tag g-tag-orange"></span></td><td><a class="g-action">发券挽回</a></td></tr>
<tr><td>陈*</td><td>177****8901</td><td>2025-12-28</td><td>&yen;3,420</td><td>36</td><td><span class="g-tag g-tag-blue"></span></td><td><a class="g-action">发券挽回</a></td></tr>
<tr><td>刘*强</td><td>155****2345</td><td>2026-01-03</td><td>&yen;720</td><td>30</td><td><span class="g-tag g-tag-blue"></span></td><td><a class="g-action">发券挽回</a></td></tr>
</tbody>
</table>
</div>
<!-- Tab4: 复购周期 -->
<div id="scTabRepurchase" class="sc-tab-panel">
<div class="sc-section-hd">复购周期分布</div>
<div class="sc-hbar-desc">分析客户两次消费之间的间隔天数分布,帮助制定精准的复购提醒策略。</div>
<div class="sc-hbar-wrap">
<div class="sc-hbar-item"><span class="sc-hbar-label">1-3 天</span><div class="sc-hbar-track"><div class="sc-hbar-fill" style="width:65%;"><span>486人</span></div></div><span class="sc-hbar-val">占 32.4%</span></div>
<div class="sc-hbar-item"><span class="sc-hbar-label">4-7 天</span><div class="sc-hbar-track"><div class="sc-hbar-fill" style="width:50%;"><span>375人</span></div></div><span class="sc-hbar-val">占 25.0%</span></div>
<div class="sc-hbar-item"><span class="sc-hbar-label">8-14 天</span><div class="sc-hbar-track"><div class="sc-hbar-fill" style="width:30%;"><span>225人</span></div></div><span class="sc-hbar-val">占 15.0%</span></div>
<div class="sc-hbar-item"><span class="sc-hbar-label">15-30 天</span><div class="sc-hbar-track"><div class="sc-hbar-fill" style="width:25%;"><span>210人</span></div></div><span class="sc-hbar-val">占 14.0%</span></div>
<div class="sc-hbar-item"><span class="sc-hbar-label">30 天+</span><div class="sc-hbar-track"><div class="sc-hbar-fill" style="width:17%;background:linear-gradient(90deg,#fa8c16,#ffc069);"><span>204人</span></div></div><span class="sc-hbar-val">占 13.6%</span></div>
</div>
<div class="sc-section-hd">复购率趋势近6个月</div>
<table class="g-table">
<thead><tr><th>月份</th><th>总客户</th><th>复购客户</th><th>复购率</th><th>环比</th></tr></thead>
<tbody>
<tr><td>2025-08</td><td>680</td><td>245</td><td>36.0%</td><td></td></tr>
<tr><td>2025-09</td><td>720</td><td>268</td><td>37.2%</td><td><span style="color:var(--g-success)">+1.2%</span></td></tr>
<tr><td>2025-10</td><td>785</td><td>306</td><td>39.0%</td><td><span style="color:var(--g-success)">+1.8%</span></td></tr>
<tr><td>2025-11</td><td>810</td><td>324</td><td>40.0%</td><td><span style="color:var(--g-success)">+1.0%</span></td></tr>
<tr><td>2025-12</td><td>856</td><td>350</td><td>40.9%</td><td><span style="color:var(--g-success)">+0.9%</span></td></tr>
<tr><td>2026-01</td><td>892</td><td>379</td><td>42.5%</td><td><span style="color:var(--g-success)">+1.6%</span></td></tr>
</tbody>
</table>
</div>
</div>
</div>
<script>
/* Tab 切换 */
function switchScTab(el, tab) {
el.closest('.g-seg').querySelectorAll('.g-seg-item').forEach(function(s) { s.classList.remove('active'); });
el.classList.add('active');
document.querySelectorAll('.sc-tab-panel').forEach(function(p) { p.classList.remove('active'); });
var map = { overview:'scTabOverview', rfm:'scTabRfm', churn:'scTabChurn', repurchase:'scTabRepurchase' };
document.getElementById(map[tab]).classList.add('active');
}
/* Lucide Icons */
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
</script>