228 lines
19 KiB
HTML
228 lines
19 KiB
HTML
<!-- 工作台 Dashboard -->
|
||
<style>
|
||
.dashboard { display:flex; flex-direction:column; gap:16px; }
|
||
.dash-row { display:grid; gap:16px; }
|
||
.dash-row.kpi { grid-template-columns:repeat(4,1fr); }
|
||
.dash-row.mid { grid-template-columns:2fr 1fr; }
|
||
.dash-row.bot { grid-template-columns:1fr 1fr 1fr; }
|
||
|
||
.kpi-card { border-radius:10px; padding:20px 24px; color:#fff; position:relative; overflow:hidden; min-height:120px; display:flex; flex-direction:column; justify-content:space-between; box-shadow:var(--g-shadow-sm); transition:var(--g-transition); }
|
||
.kpi-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-2px); }
|
||
.kpi-card::before { content:""; position:absolute; top:-30px; right:-30px; width:100px; height:100px; border-radius:50%; background:rgba(255,255,255,0.1); }
|
||
.kpi-card::after { content:""; position:absolute; bottom:-20px; right:30px; width:60px; height:60px; border-radius:50%; background:rgba(255,255,255,0.08); }
|
||
.kpi-card.c1 { background:linear-gradient(135deg,#1890ff,#096dd9); }
|
||
.kpi-card.c2 { background:linear-gradient(135deg,#22c55e,#16a34a); }
|
||
.kpi-card.c3 { background:linear-gradient(135deg,#f59e0b,#d97706); }
|
||
.kpi-card.c4 { background:linear-gradient(135deg,#722ed1,#531dab); }
|
||
.kpi-top { display:flex; align-items:center; justify-content:space-between; }
|
||
.kpi-label { font-size:13px; opacity:0.85; }
|
||
.kpi-icon { width:40px; height:40px; border-radius:10px; background:rgba(255,255,255,0.2); display:flex; align-items:center; justify-content:center; }
|
||
.kpi-value { font-size:34px; font-weight:800; letter-spacing:-1px; margin:8px 0 4px; }
|
||
.kpi-sub { font-size:12px; opacity:0.75; display:flex; align-items:center; gap:4px; }
|
||
.kpi-sub .up { color:#b7eb8f; }
|
||
.kpi-sub .down { color:#fecaca; }
|
||
|
||
.dash-card-more { font-size:12px; color:#9ca3af; font-weight:400; cursor:pointer; transition:var(--g-transition); }
|
||
.dash-card-more:hover { color:var(--primary); }
|
||
|
||
.bar-chart { display:flex; align-items:flex-end; gap:10px; height:200px; padding-top:10px; }
|
||
.bar-chart-wrap { display:flex; height:200px; }
|
||
.bar-y-axis { display:flex; flex-direction:column; justify-content:space-between; padding-right:8px; font-size:11px; color:#9ca3af; text-align:right; min-width:36px; padding-bottom:22px; }
|
||
.bar-chart-body { flex:1; display:flex; align-items:flex-end; gap:10px; }
|
||
.bar-col { flex:1; display:flex; flex-direction:column; align-items:center; gap:6px; }
|
||
.bar-wrap { width:100%; display:flex; gap:4px; justify-content:center; height:170px; align-items:flex-end; }
|
||
.bar { width:18px; border-radius:4px 4px 0 0; transition:height 0.6s cubic-bezier(0.2,0,0,1); cursor:pointer; }
|
||
.bar:hover { opacity:0.85; }
|
||
.bar.income { background:linear-gradient(180deg,#1890ff,#69c0ff); }
|
||
.bar.orders { background:linear-gradient(180deg,#22c55e,#86efac); }
|
||
.bar-label { font-size:11px; color:#9ca3af; }
|
||
|
||
.donut-wrap { display:flex; align-items:center; gap:24px; padding:10px 0; }
|
||
.donut { width:140px; height:140px; border-radius:50%; position:relative; flex-shrink:0; }
|
||
.donut-center { position:absolute; inset:30px; background:#fff; border-radius:50%; display:flex; flex-direction:column; align-items:center; justify-content:center; }
|
||
.donut-center .num { font-size:24px; font-weight:800; color:#1a1a2e; }
|
||
.donut-center .txt { font-size:11px; color:#9ca3af; }
|
||
.donut-legend { display:flex; flex-direction:column; gap:10px; flex:1; }
|
||
.legend-item { display:flex; align-items:center; gap:8px; font-size:13px; color:#1a1a2e; }
|
||
.legend-dot { width:8px; height:8px; border-radius:2px; flex-shrink:0; }
|
||
.legend-val { margin-left:auto; font-weight:600; }
|
||
|
||
.rank-list { display:flex; flex-direction:column; gap:12px; }
|
||
.rank-item { display:flex; align-items:center; gap:10px; }
|
||
.rank-num { width:20px; height:20px; border-radius:4px; display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:600; color:#fff; flex-shrink:0; }
|
||
.rank-num.t1 { background:linear-gradient(135deg,#ef4444,#f97316); }
|
||
.rank-num.t2 { background:linear-gradient(135deg,#f59e0b,#fbbf24); }
|
||
.rank-num.t3 { background:linear-gradient(135deg,#1890ff,#69c0ff); }
|
||
.rank-num.tn { background:#e5e7eb; color:#4b5563; }
|
||
.rank-name { font-size:13px; color:#1a1a2e; flex:1; }
|
||
.rank-bar-bg { width:100px; height:6px; background:#e5e7eb; border-radius:3px; overflow:hidden; }
|
||
.rank-bar-fill { height:100%; border-radius:3px; background:linear-gradient(90deg,#1890ff,#69c0ff); }
|
||
.rank-count { font-size:12px; color:#9ca3af; width:40px; text-align:right; font-weight:600; }
|
||
|
||
.feed-list { display:flex; flex-direction:column; max-height:320px; overflow-y:auto; }
|
||
.feed-list::-webkit-scrollbar { width:3px; }
|
||
.feed-list::-webkit-scrollbar-thumb { background:#e5e7eb; border-radius:2px; }
|
||
.feed-item { display:flex; align-items:center; gap:10px; padding:10px 0; border-bottom:1px solid #f3f4f6; transition:var(--g-transition); }
|
||
.feed-item:hover { background:color-mix(in srgb, var(--primary) 3%, #fff); }
|
||
.feed-item:last-child { border-bottom:none; }
|
||
.feed-avatar { width:32px; height:32px; border-radius:50%; background:#f8f9fb; display:flex; align-items:center; justify-content:center; font-size:12px; flex-shrink:0; color:#4b5563; }
|
||
.feed-info { flex:1; }
|
||
.feed-info .top { font-size:13px; color:#1a1a2e; display:flex; justify-content:space-between; }
|
||
.feed-info .bot { font-size:11px; color:#9ca3af; margin-top:3px; }
|
||
.feed-badge { padding:2px 8px; border-radius:6px; font-size:11px; white-space:nowrap; font-weight:600; }
|
||
.feed-badge.new { background:#eff6ff; color:#2563eb; }
|
||
.feed-badge.cooking { background:#fffbeb; color:#d97706; }
|
||
.feed-badge.delivering { background:#f0fdf4; color:#16a34a; }
|
||
.feed-badge.done { background:#f8f9fb; color:#9ca3af; }
|
||
|
||
.alert-list { display:flex; flex-direction:column; gap:8px; }
|
||
.alert-item { display:flex; align-items:center; gap:10px; padding:10px 12px; border-radius:8px; font-size:13px; transition:var(--g-transition); cursor:pointer; }
|
||
.alert-item:hover { filter:brightness(0.97); transform:translateX(2px); }
|
||
.alert-item.warn { background:#fffbeb; border:1px solid #fde68a; color:#92400e; }
|
||
.alert-item.danger { background:#fef2f2; border:1px solid #fecaca; color:#991b1b; }
|
||
.alert-item.info { background:#eff6ff; border:1px solid #bfdbfe; color:#1e40af; }
|
||
.alert-icon { flex-shrink:0; }
|
||
|
||
.quota-item { display:flex; flex-direction:column; gap:6px; margin-bottom:14px; }
|
||
.quota-item:last-child { margin-bottom:0; }
|
||
.quota-head { display:flex; justify-content:space-between; font-size:13px; }
|
||
.quota-name { color:#1a1a2e; font-weight:500; }
|
||
.quota-val { color:#9ca3af; }
|
||
.quota-bar { height:8px; background:#e5e7eb; border-radius:4px; overflow:hidden; }
|
||
.quota-fill { height:100%; border-radius:4px; transition:width 0.6s; }
|
||
.quota-fill.ok { background:linear-gradient(90deg,#1890ff,#69c0ff); }
|
||
.quota-fill.mid { background:linear-gradient(90deg,#f59e0b,#fbbf24); }
|
||
.quota-fill.high { background:linear-gradient(90deg,#ef4444,#f97316); }
|
||
|
||
@keyframes fadeInUp { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:translateY(0); } }
|
||
.dashboard .dash-row > * { animation: fadeInUp 0.4s ease both; }
|
||
.dashboard .dash-row > *:nth-child(2) { animation-delay:0.05s; }
|
||
.dashboard .dash-row > *:nth-child(3) { animation-delay:0.1s; }
|
||
.dashboard .dash-row > *:nth-child(4) { animation-delay:0.15s; }
|
||
</style>
|
||
|
||
<div class="dashboard">
|
||
<!-- Date Picker -->
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:-8px">
|
||
<div style="font-size:15px;font-weight:600;color:#1a1a2e">数据概览</div>
|
||
<div style="display:flex;align-items:center;gap:8px">
|
||
<span style="font-size:13px;color:#666">日期</span>
|
||
<input type="date" class="g-input" style="width:140px;height:30px;font-size:12px" value="2025-01-15">
|
||
<span style="font-size:13px;color:#999">至</span>
|
||
<input type="date" class="g-input" style="width:140px;height:30px;font-size:12px" value="2025-01-15">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- KPI -->
|
||
<div class="dash-row kpi">
|
||
<div class="kpi-card c1">
|
||
<div class="kpi-top"><span class="kpi-label">今日订单</span><div class="kpi-icon"><i data-lucide="shopping-bag" style="width:20px;height:20px;"></i></div></div>
|
||
<div class="kpi-value">386</div>
|
||
<div class="kpi-sub"><span class="up">+12.5%</span> 较昨日</div>
|
||
</div>
|
||
<div class="kpi-card c2">
|
||
<div class="kpi-top"><span class="kpi-label">今日营收</span><div class="kpi-icon"><i data-lucide="trending-up" style="width:20px;height:20px;"></i></div></div>
|
||
<div class="kpi-value">¥12,680</div>
|
||
<div class="kpi-sub"><span class="up">+8.3%</span> 较昨日</div>
|
||
</div>
|
||
<div class="kpi-card c3">
|
||
<div class="kpi-top"><span class="kpi-label">客单价</span><div class="kpi-icon"><i data-lucide="receipt" style="width:20px;height:20px;"></i></div></div>
|
||
<div class="kpi-value">¥32.8</div>
|
||
<div class="kpi-sub"><span class="down">-2.1%</span> 较昨日</div>
|
||
</div>
|
||
<div class="kpi-card c4">
|
||
<div class="kpi-top"><span class="kpi-label">新增客户</span><div class="kpi-icon"><i data-lucide="user-plus" style="width:20px;height:20px;"></i></div></div>
|
||
<div class="kpi-value">57</div>
|
||
<div class="kpi-sub"><span class="up">+23.9%</span> 较昨日</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Revenue Chart + Order Status -->
|
||
<div class="dash-row mid">
|
||
<div class="g-card" style="padding:0;">
|
||
<div class="g-card-title" style="padding:14px 18px; margin-bottom:0; border-bottom:1px solid #f5f5f5; display:flex; align-items:center; justify-content:space-between;">近7日营收趋势<span class="dash-card-more">查看详情 →</span></div>
|
||
<div style="padding:16px 18px;">
|
||
<div class="bar-chart-wrap">
|
||
<div class="bar-y-axis"><span>¥15k</span><span>¥12k</span><span>¥9k</span><span>¥6k</span><span>¥3k</span><span>0</span></div>
|
||
<div class="bar-chart">
|
||
<div class="bar-col"><div class="bar-wrap"><div class="bar income" style="height:60%;"></div><div class="bar orders" style="height:45%;"></div></div><span class="bar-label">周一</span></div>
|
||
<div class="bar-col"><div class="bar-wrap"><div class="bar income" style="height:75%;"></div><div class="bar orders" style="height:55%;"></div></div><span class="bar-label">周二</span></div>
|
||
<div class="bar-col"><div class="bar-wrap"><div class="bar income" style="height:55%;"></div><div class="bar orders" style="height:40%;"></div></div><span class="bar-label">周三</span></div>
|
||
<div class="bar-col"><div class="bar-wrap"><div class="bar income" style="height:85%;"></div><div class="bar orders" style="height:65%;"></div></div><span class="bar-label">周四</span></div>
|
||
<div class="bar-col"><div class="bar-wrap"><div class="bar income" style="height:95%;"></div><div class="bar orders" style="height:72%;"></div></div><span class="bar-label">周五</span></div>
|
||
<div class="bar-col"><div class="bar-wrap"><div class="bar income" style="height:100%;"></div><div class="bar orders" style="height:80%;"></div></div><span class="bar-label">周六</span></div>
|
||
<div class="bar-col"><div class="bar-wrap"><div class="bar income" style="height:90%;"></div><div class="bar orders" style="height:70%;"></div></div><span class="bar-label">周日</span></div>
|
||
</div>
|
||
</div>
|
||
<div style="display:flex;gap:16px;justify-content:center;margin-top:10px;font-size:12px;color:#999;">
|
||
<span><span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#1890ff;margin-right:4px;"></span>营收</span>
|
||
<span><span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:#52c41a;margin-right:4px;"></span>订单量</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="g-card" style="padding:0;">
|
||
<div class="g-card-title" style="padding:14px 18px; margin-bottom:0; border-bottom:1px solid #f5f5f5; display:flex; align-items:center; justify-content:space-between;">今日订单状态</div>
|
||
<div style="padding:16px 18px;">
|
||
<div class="donut-wrap">
|
||
<div class="donut" style="background:conic-gradient(#1890ff 0% 15%,#fa8c16 15% 30%,#52c41a 30% 55%,#722ed1 55% 75%,#d9d9d9 75% 100%);">
|
||
<div class="donut-center"><span class="num">386</span><span class="txt">总订单</span></div>
|
||
</div>
|
||
<div class="donut-legend">
|
||
<div class="legend-item"><span class="legend-dot" style="background:#1890ff;"></span>待接单<span class="legend-val">58</span></div>
|
||
<div class="legend-item"><span class="legend-dot" style="background:#fa8c16;"></span>制作中<span class="legend-val">59</span></div>
|
||
<div class="legend-item"><span class="legend-dot" style="background:#52c41a;"></span>配送中<span class="legend-val">96</span></div>
|
||
<div class="legend-item"><span class="legend-dot" style="background:#722ed1;"></span>已完成<span class="legend-val">77</span></div>
|
||
<div class="legend-item"><span class="legend-dot" style="background:#d9d9d9;"></span>已取消<span class="legend-val">96</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Ranking + Feed + Alerts -->
|
||
<div class="dash-row bot">
|
||
<div class="g-card" style="padding:0;">
|
||
<div class="g-card-title" style="padding:14px 18px; margin-bottom:0; border-bottom:1px solid #f5f5f5; display:flex; align-items:center; justify-content:space-between;">热销菜品 TOP5<span class="dash-card-more">更多 →</span></div>
|
||
<div style="padding:16px 18px;">
|
||
<div class="rank-list">
|
||
<div class="rank-item"><span class="rank-num t1">1</span><span class="rank-name">招牌红烧肉饭</span><div class="rank-bar-bg"><div class="rank-bar-fill" style="width:100%;"></div></div><span class="rank-count">128</span></div>
|
||
<div class="rank-item"><span class="rank-num t2">2</span><span class="rank-name">香辣鸡腿堡套餐</span><div class="rank-bar-bg"><div class="rank-bar-fill" style="width:78%;"></div></div><span class="rank-count">99</span></div>
|
||
<div class="rank-item"><span class="rank-num t3">3</span><span class="rank-name">番茄牛腩面</span><div class="rank-bar-bg"><div class="rank-bar-fill" style="width:62%;"></div></div><span class="rank-count">79</span></div>
|
||
<div class="rank-item"><span class="rank-num tn">4</span><span class="rank-name">鱼香肉丝盖饭</span><div class="rank-bar-bg"><div class="rank-bar-fill" style="width:45%;"></div></div><span class="rank-count">58</span></div>
|
||
<div class="rank-item"><span class="rank-num tn">5</span><span class="rank-name">冰柠檬红茶</span><div class="rank-bar-bg"><div class="rank-bar-fill" style="width:35%;"></div></div><span class="rank-count">45</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="g-card" style="padding:0;">
|
||
<div class="g-card-title" style="padding:14px 18px; margin-bottom:0; border-bottom:1px solid #f5f5f5; display:flex; align-items:center; justify-content:space-between;">实时订单<span class="dash-card-more">全部订单 →</span></div>
|
||
<div style="padding:8px 18px;">
|
||
<div class="feed-list">
|
||
<div class="feed-item"><div class="feed-avatar">张</div><div class="feed-info"><div class="top"><span>#20260211001</span><span>¥45.5</span></div><div class="bot">张先生 · 朝阳店 · 2分钟前</div></div><span class="feed-badge new">待接单</span></div>
|
||
<div class="feed-item"><div class="feed-avatar">李</div><div class="feed-info"><div class="top"><span>#20260211002</span><span>¥68.0</span></div><div class="bot">李女士 · 海淀店 · 5分钟前</div></div><span class="feed-badge cooking">制作中</span></div>
|
||
<div class="feed-item"><div class="feed-avatar">王</div><div class="feed-info"><div class="top"><span>#20260211003</span><span>¥32.0</span></div><div class="bot">王先生 · 望京店 · 12分钟前</div></div><span class="feed-badge delivering">配送中</span></div>
|
||
<div class="feed-item"><div class="feed-avatar">赵</div><div class="feed-info"><div class="top"><span>#20260211004</span><span>¥55.5</span></div><div class="bot">赵女士 · 朝阳店 · 18分钟前</div></div><span class="feed-badge done">已完成</span></div>
|
||
<div class="feed-item"><div class="feed-avatar">刘</div><div class="feed-info"><div class="top"><span>#20260211005</span><span>¥28.0</span></div><div class="bot">刘先生 · 通州店 · 25分钟前</div></div><span class="feed-badge done">已完成</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="g-card" style="padding:0;">
|
||
<div class="g-card-title" style="padding:14px 18px; margin-bottom:0; border-bottom:1px solid #f5f5f5; display:flex; align-items:center; justify-content:space-between;">运营提醒</div>
|
||
<div style="padding:16px 18px;">
|
||
<div class="alert-list">
|
||
<div class="alert-item danger"><i data-lucide="alert-triangle" style="width:16px;height:16px;" class="alert-icon"></i>3款商品库存不足,请及时补货</div>
|
||
<div class="alert-item warn"><i data-lucide="clock" style="width:16px;height:16px;" class="alert-icon"></i>食品经营许可证将于30天后到期</div>
|
||
<div class="alert-item warn"><i data-lucide="message-square" style="width:16px;height:16px;" class="alert-icon"></i>5条新评价待回复</div>
|
||
<div class="alert-item info"><i data-lucide="gift" style="width:16px;height:16px;" class="alert-icon"></i>满减活动明日到期,建议续期</div>
|
||
</div>
|
||
<div style="margin-top:16px;">
|
||
<div style="font-size:13px;font-weight:600;color:#333;margin-bottom:10px;">套餐配额</div>
|
||
<div class="quota-item"><div class="quota-head"><span class="quota-name">门店数量</span><span class="quota-val">5 / 10</span></div><div class="quota-bar"><div class="quota-fill ok" style="width:50%;"></div></div></div>
|
||
<div class="quota-item"><div class="quota-head"><span class="quota-name">员工账号</span><span class="quota-val">18 / 20</span></div><div class="quota-bar"><div class="quota-fill high" style="width:90%;"></div></div></div>
|
||
<div class="quota-item"><div class="quota-head"><span class="quota-name">短信额度</span><span class="quota-val">320 / 1000</span></div><div class="quota-bar"><div class="quota-fill ok" style="width:32%;"></div></div></div>
|
||
<div class="quota-item"><div class="quota-head"><span class="quota-name">存储空间</span><span class="quota-val">1.8G / 5G</span></div><div class="quota-bar"><div class="quota-fill mid" style="width:36%;"></div></div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|