feat: 设备端-结算设备菜单化+营养评分屏扩展+LED屏重构
- checkout-device/index.html 由占位改为三菜单入口(结算/小票/查询),增加 PAD 外壳样式 - 新增 checkout-device/02-print-receipt.html 打印小票原型 - nutrition-score-screen/index.html 大幅扩展:实时营养得分看板、用户排行榜、餐品热度 - led-food-display/index.html 简化为引用实拍图版本,新增 led-v2.jpg - canteen-device/index.html 导航:结算设备、营养得分屏标记为「已设计」 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
e157638168
commit
836b05383d
@@ -0,0 +1,890 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>结算设备 - 打印小票预览 | 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
/* 外层视口:全屏深色背景,承载居中 PAD 外壳 */
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
/* PAD 设备外壳 */
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: #0e1326;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
/* 顶部导航栏 */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
background: #1a2b4a;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.back-btn {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.back-btn:hover { color: #fff; }
|
||||
.top-bar__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
.top-bar__meta {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* 主体:左右两列 */
|
||||
.page-body {
|
||||
display: grid;
|
||||
grid-template-columns: 340px 1fr;
|
||||
height: calc(100% - 44px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ===== 左列:订单列表 ===== */
|
||||
.left-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.06);
|
||||
background: rgba(26, 43, 74, 0.3);
|
||||
}
|
||||
.filter-bar {
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.filter-select {
|
||||
flex: 1;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
padding: 6px 10px;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-family: inherit;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.filter-select:focus { border-color: #4a90d9; }
|
||||
|
||||
.order-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.order-list::-webkit-scrollbar { display: none; }
|
||||
|
||||
.order-card {
|
||||
background: #1a2b4a;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
position: relative;
|
||||
}
|
||||
.order-card:hover {
|
||||
border-color: rgba(74, 144, 217, 0.4);
|
||||
background: rgba(74, 144, 217, 0.08);
|
||||
}
|
||||
.order-card.active {
|
||||
border-color: #4a90d9;
|
||||
background: rgba(74, 144, 217, 0.12);
|
||||
box-shadow: 0 0 0 1px rgba(74, 144, 217, 0.3);
|
||||
}
|
||||
.order-card.printed {
|
||||
opacity: 0.55;
|
||||
}
|
||||
.order-card__row1 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.order-card__id {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.meal-tag {
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
padding: 3px 7px;
|
||||
border-radius: 9px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.meal-tag--breakfast {
|
||||
background: rgba(250, 140, 22, 0.18);
|
||||
color: #fb923c;
|
||||
border: 1px solid rgba(250, 140, 22, 0.35);
|
||||
}
|
||||
.meal-tag--lunch {
|
||||
background: rgba(37, 99, 235, 0.18);
|
||||
color: #60a5fa;
|
||||
border: 1px solid rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
.meal-tag--dinner {
|
||||
background: rgba(34, 197, 94, 0.18);
|
||||
color: #4ade80;
|
||||
border: 1px solid rgba(34, 197, 94, 0.35);
|
||||
}
|
||||
.order-card__row2 {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.order-card__time {
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.order-card__amount {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #0AC4A8;
|
||||
}
|
||||
.order-card__status {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
font-size: 9px;
|
||||
line-height: 1;
|
||||
padding: 3px 6px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.order-card__status--printed {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
.order-card__status--pending {
|
||||
background: rgba(234, 88, 12, 0.18);
|
||||
color: #fb923c;
|
||||
border: 1px solid rgba(234, 88, 12, 0.35);
|
||||
}
|
||||
|
||||
/* ===== 右列:小票预览 ===== */
|
||||
.right-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.receipt-stage {
|
||||
flex: 1;
|
||||
padding: 24px 32px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
scrollbar-width: none;
|
||||
background: linear-gradient(180deg, rgba(10, 16, 32, 0.4), rgba(10, 16, 32, 0.8));
|
||||
}
|
||||
.receipt-stage::-webkit-scrollbar { display: none; }
|
||||
|
||||
/* 热敏小票纸 */
|
||||
.receipt-paper {
|
||||
width: 300px;
|
||||
background: #fff;
|
||||
color: #1a1a2e;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
padding: 16px 18px;
|
||||
font-family: Menlo, Consolas, "Courier New", monospace;
|
||||
font-size: 11px;
|
||||
line-height: 1.6;
|
||||
position: relative;
|
||||
}
|
||||
/* 模拟热敏纸撕扯边缘 */
|
||||
.receipt-paper::before,
|
||||
.receipt-paper::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 6px;
|
||||
background-image: linear-gradient(45deg, transparent 50%, #fff 50%), linear-gradient(-45deg, transparent 50%, #fff 50%);
|
||||
background-size: 8px 6px;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.receipt-paper::before {
|
||||
top: -6px;
|
||||
}
|
||||
.receipt-paper::after {
|
||||
bottom: -6px;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* 食堂抬头 */
|
||||
.receipt-header { text-align: center; padding: 4px 0 8px; }
|
||||
.receipt-name {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #1a1a2e;
|
||||
margin-bottom: 4px;
|
||||
font-family: -apple-system, "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
.receipt-sub {
|
||||
font-size: 10px;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 分割线 */
|
||||
.receipt-divider {
|
||||
border-top: 1px dashed #999;
|
||||
margin: 8px 0;
|
||||
}
|
||||
.receipt-divider--double {
|
||||
border-top: 1px dashed #999;
|
||||
border-bottom: 1px dashed #999;
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
/* 通用信息行 */
|
||||
.receipt-info { display: flex; flex-direction: column; gap: 2px; }
|
||||
.receipt-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
font-size: 11px;
|
||||
}
|
||||
.receipt-row__label { color: #666; }
|
||||
.receipt-row__value { color: #1a1a2e; font-weight: 600; }
|
||||
|
||||
/* 消费明细表 */
|
||||
.receipt-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 11px;
|
||||
font-family: Menlo, Consolas, monospace;
|
||||
}
|
||||
.receipt-table th {
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
padding: 4px 0;
|
||||
border-bottom: 1px dashed #999;
|
||||
text-align: left;
|
||||
}
|
||||
.receipt-table th:nth-child(2),
|
||||
.receipt-table th:nth-child(3),
|
||||
.receipt-table th:nth-child(4) { text-align: right; }
|
||||
.receipt-table td {
|
||||
padding: 3px 0;
|
||||
color: #1a1a2e;
|
||||
vertical-align: top;
|
||||
}
|
||||
.receipt-table td:nth-child(2),
|
||||
.receipt-table td:nth-child(3),
|
||||
.receipt-table td:nth-child(4) { text-align: right; }
|
||||
.receipt-table td:nth-child(3) { color: #666; }
|
||||
|
||||
/* 金额汇总 */
|
||||
.receipt-amount {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
}
|
||||
.receipt-amount__payable {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
.receipt-amount__paid {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #0a7c64;
|
||||
}
|
||||
|
||||
/* 营养摄入摘要 */
|
||||
.receipt-nutrition-title {
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
color: #666;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.receipt-nutrition-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 4px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.nutrition-item {
|
||||
text-align: center;
|
||||
padding: 4px 2px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.nutrition-item__label {
|
||||
font-size: 9px;
|
||||
color: #999;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.nutrition-item__value {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
.nutrition-item__value small {
|
||||
font-size: 9px;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
margin-left: 1px;
|
||||
}
|
||||
.receipt-score {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6px 10px;
|
||||
background: linear-gradient(90deg, #f0f7ff, #e6f4ff);
|
||||
border-radius: 4px;
|
||||
border: 1px solid #cce4ff;
|
||||
}
|
||||
.receipt-score__label {
|
||||
font-size: 10px;
|
||||
color: #4a90d9;
|
||||
font-weight: 600;
|
||||
}
|
||||
.receipt-score__value {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #2570c0;
|
||||
}
|
||||
|
||||
/* 二维码 */
|
||||
.receipt-qr {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
.receipt-qr__img {
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
}
|
||||
.receipt-qr__text {
|
||||
font-size: 9px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 底部提示 */
|
||||
.receipt-footer {
|
||||
text-align: center;
|
||||
padding: 4px 0;
|
||||
}
|
||||
.receipt-footer__line1 {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #1a1a2e;
|
||||
margin-bottom: 2px;
|
||||
font-family: -apple-system, "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
.receipt-footer__line2 {
|
||||
font-size: 10px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.action-bar {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: center;
|
||||
padding: 12px 20px;
|
||||
background: rgba(10, 16, 32, 0.6);
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.06);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.btn {
|
||||
padding: 10px 28px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-family: inherit;
|
||||
}
|
||||
.btn--primary {
|
||||
background: #4a90d9;
|
||||
color: #fff;
|
||||
}
|
||||
.btn--primary:hover {
|
||||
background: #3a7bc8;
|
||||
box-shadow: 0 4px 14px rgba(74, 144, 217, 0.35);
|
||||
}
|
||||
.btn--primary:active { transform: scale(0.97); }
|
||||
.btn--ghost {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
.btn--ghost:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: #fff;
|
||||
border-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.btn--success {
|
||||
background: #52c41a;
|
||||
color: #fff;
|
||||
}
|
||||
.btn--success:hover {
|
||||
background: #45a818;
|
||||
box-shadow: 0 4px 14px rgba(82, 196, 26, 0.35);
|
||||
}
|
||||
.btn--success:active { transform: scale(0.97); }
|
||||
|
||||
/* Toast */
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-20px);
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
color: #fff;
|
||||
padding: 12px 28px;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
max-width: 90%;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.toast.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
.toast--success { background: rgba(82, 196, 26, 0.92); }
|
||||
.toast--warn { background: rgba(250, 173, 22, 0.92); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<a class="back-btn" href="index.html">◀ 返回</a>
|
||||
<span class="top-bar__title">打印小票预览</span>
|
||||
<span class="top-bar__meta" id="topMeta">2026-08-03</span>
|
||||
</div>
|
||||
|
||||
<!-- 主体 -->
|
||||
<div class="page-body">
|
||||
|
||||
<!-- 左列:订单列表 -->
|
||||
<div class="left-col">
|
||||
<div class="filter-bar">
|
||||
<select class="filter-select" id="mealFilter" onchange="renderOrderList()">
|
||||
<option value="all">全部餐次</option>
|
||||
<option value="breakfast">早餐</option>
|
||||
<option value="lunch">午餐</option>
|
||||
<option value="dinner">晚餐</option>
|
||||
</select>
|
||||
<select class="filter-select" id="statusFilter" onchange="renderOrderList()">
|
||||
<option value="all">全部状态</option>
|
||||
<option value="pending">未打印</option>
|
||||
<option value="printed">已打印</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="order-list" id="orderList"></div>
|
||||
</div>
|
||||
|
||||
<!-- 右列:小票预览 -->
|
||||
<div class="right-col">
|
||||
<div class="receipt-stage" id="receiptStage"></div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn--ghost" onclick="window.location.href='index.html'">◀ 返回</button>
|
||||
<button class="btn btn--success" id="printBtn" onclick="handlePrint()">🖨️ 打印小票</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Toast -->
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<script>
|
||||
/* ==================== Mock 订单数据 ==================== */
|
||||
var mockOrders = [
|
||||
{
|
||||
id: 'CO-20260803-001',
|
||||
mealType: 'lunch',
|
||||
mealLabel: '午餐',
|
||||
line: 'A 区 1 号餐线',
|
||||
cashier: '张三',
|
||||
time: '2026-08-03 12:15:30',
|
||||
items: [
|
||||
{ name: '宫保鸡丁', price: 18.00, qty: 1, subtotal: 18.00 },
|
||||
{ name: '番茄炒蛋', price: 8.00, qty: 1, subtotal: 8.00 },
|
||||
{ name: '米饭', price: 2.00, qty: 1, subtotal: 2.00 },
|
||||
{ name: '紫菜蛋花汤', price: 5.00, qty: 1, subtotal: 5.00 }
|
||||
],
|
||||
total: 33.00, discount: 3.00, payable: 30.00, paid: 30.00,
|
||||
payMethod: '人脸支付', balance: 1280.50,
|
||||
nutrition: { calories: 685, protein: 28, fat: 18, carb: 95, score: 82 },
|
||||
printed: true
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-008',
|
||||
mealType: 'breakfast',
|
||||
mealLabel: '早餐',
|
||||
line: 'A 区 1 号餐线',
|
||||
cashier: '张三',
|
||||
time: '2026-08-03 07:42:18',
|
||||
items: [
|
||||
{ name: '豆浆', price: 3.00, qty: 1, subtotal: 3.00 },
|
||||
{ name: '油条', price: 2.50, qty: 2, subtotal: 5.00 },
|
||||
{ name: '茶叶蛋', price: 4.00, qty: 1, subtotal: 4.00 }
|
||||
],
|
||||
total: 12.00, discount: 0, payable: 12.00, paid: 12.00,
|
||||
payMethod: '餐卡支付', balance: 1292.50,
|
||||
nutrition: { calories: 425, protein: 15, fat: 12, carb: 60, score: 75 },
|
||||
printed: true
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-015',
|
||||
mealType: 'lunch',
|
||||
mealLabel: '午餐',
|
||||
line: 'A 区 2 号餐线',
|
||||
cashier: '李四',
|
||||
time: '2026-08-03 12:32:45',
|
||||
items: [
|
||||
{ name: '红烧肉', price: 22.00, qty: 1, subtotal: 22.00 },
|
||||
{ name: '清炒时蔬', price: 6.00, qty: 1, subtotal: 6.00 },
|
||||
{ name: '鱼香肉丝', price: 12.00, qty: 1, subtotal: 12.00 },
|
||||
{ name: '米饭', price: 2.00, qty: 1, subtotal: 2.00 },
|
||||
{ name: '冬瓜排骨汤', price: 3.00, qty: 1, subtotal: 3.00 }
|
||||
],
|
||||
total: 45.00, discount: 5.00, payable: 40.00, paid: 40.00,
|
||||
payMethod: '人脸支付', balance: 1240.50,
|
||||
nutrition: { calories: 720, protein: 35, fat: 28, carb: 88, score: 88 },
|
||||
printed: false
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-022',
|
||||
mealType: 'dinner',
|
||||
mealLabel: '晚餐',
|
||||
line: 'A 区 1 号餐线',
|
||||
cashier: '王五',
|
||||
time: '2026-08-03 18:15:20',
|
||||
items: [
|
||||
{ name: '清蒸鲈鱼', price: 25.00, qty: 1, subtotal: 25.00 },
|
||||
{ name: '蒜蓉西兰花', price: 6.00, qty: 1, subtotal: 6.00 },
|
||||
{ name: '紫米饭', price: 3.00, qty: 1, subtotal: 3.00 }
|
||||
],
|
||||
total: 28.00, discount: 0, payable: 28.00, paid: 28.00,
|
||||
payMethod: '扫码支付', balance: 1212.50,
|
||||
nutrition: { calories: 510, protein: 32, fat: 14, carb: 65, score: 90 },
|
||||
printed: false
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-029',
|
||||
mealType: 'lunch',
|
||||
mealLabel: '午餐',
|
||||
line: 'A 区 3 号餐线',
|
||||
cashier: '张三',
|
||||
time: '2026-08-03 12:48:10',
|
||||
items: [
|
||||
{ name: '番茄炒蛋', price: 8.00, qty: 1, subtotal: 8.00 },
|
||||
{ name: '麻婆豆腐', price: 10.00, qty: 1, subtotal: 10.00 },
|
||||
{ name: '米饭', price: 2.00, qty: 1, subtotal: 2.00 },
|
||||
{ name: '番茄蛋汤', price: 5.00, qty: 1, subtotal: 5.00 }
|
||||
],
|
||||
total: 25.00, discount: 0, payable: 25.00, paid: 25.00,
|
||||
payMethod: '人脸支付', balance: 1187.50,
|
||||
nutrition: { calories: 480, protein: 22, fat: 15, carb: 70, score: 78 },
|
||||
printed: false
|
||||
},
|
||||
{
|
||||
id: 'CO-20260803-035',
|
||||
mealType: 'breakfast',
|
||||
mealLabel: '早餐',
|
||||
line: 'A 区 2 号餐线',
|
||||
cashier: '李四',
|
||||
time: '2026-08-03 08:15:30',
|
||||
items: [
|
||||
{ name: '皮蛋瘦肉粥', price: 5.00, qty: 1, subtotal: 5.00 },
|
||||
{ name: '鲜肉包子', price: 3.00, qty: 1, subtotal: 3.00 }
|
||||
],
|
||||
total: 8.00, discount: 0, payable: 8.00, paid: 8.00,
|
||||
payMethod: '餐卡支付', balance: 1195.50,
|
||||
nutrition: { calories: 320, protein: 12, fat: 8, carb: 48, score: 70 },
|
||||
printed: false
|
||||
}
|
||||
];
|
||||
|
||||
/* 食堂抬头 */
|
||||
var canteenInfo = {
|
||||
name: 'CQ 能源公司员工食堂',
|
||||
address: '重庆市渝北区星光大道 88 号',
|
||||
phone: '023-7788-XXXX'
|
||||
};
|
||||
|
||||
var currentOrderId = mockOrders[0].id;
|
||||
|
||||
/* ==================== 渲染:订单列表 ==================== */
|
||||
function renderOrderList() {
|
||||
var mealFilter = document.getElementById('mealFilter').value;
|
||||
var statusFilter = document.getElementById('statusFilter').value;
|
||||
|
||||
var filtered = mockOrders.filter(function(o) {
|
||||
if (mealFilter !== 'all' && o.mealType !== mealFilter) return false;
|
||||
if (statusFilter === 'pending' && o.printed) return false;
|
||||
if (statusFilter === 'printed' && !o.printed) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
var listEl = document.getElementById('orderList');
|
||||
if (filtered.length === 0) {
|
||||
listEl.innerHTML = '<div style="text-align:center;padding:24px 8px;color:rgba(255,255,255,0.3);font-size:12px;">无符合条件的订单</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
var html = filtered.map(function(o) {
|
||||
var mealTagClass = 'meal-tag--' + o.mealType;
|
||||
var printedClass = o.printed ? ' printed' : '';
|
||||
var activeClass = o.id === currentOrderId ? ' active' : '';
|
||||
var statusHtml = o.printed
|
||||
? '<span class="order-card__status order-card__status--printed">已打印</span>'
|
||||
: '<span class="order-card__status order-card__status--pending">未打印</span>';
|
||||
return '<div class="order-card' + activeClass + printedClass + '" onclick="selectOrder(\'' + o.id + '\')">'
|
||||
+ statusHtml
|
||||
+ '<div class="order-card__row1">'
|
||||
+ '<span class="order-card__id">' + o.id + '</span>'
|
||||
+ '<span class="meal-tag ' + mealTagClass + '">' + o.mealLabel + '</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="order-card__row2">'
|
||||
+ '<span class="order-card__time">' + o.time + '</span>'
|
||||
+ '<span class="order-card__amount">¥' + o.payable.toFixed(2) + '</span>'
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
}).join('');
|
||||
|
||||
listEl.innerHTML = html;
|
||||
}
|
||||
|
||||
/* ==================== 渲染:小票预览 ==================== */
|
||||
function renderReceipt() {
|
||||
var order = mockOrders.filter(function(o) { return o.id === currentOrderId; })[0];
|
||||
if (!order) {
|
||||
document.getElementById('receiptStage').innerHTML = '<div style="color:rgba(255,255,255,0.3);font-size:12px;">请选择左侧订单查看小票</div>';
|
||||
updatePrintBtn();
|
||||
return;
|
||||
}
|
||||
|
||||
var itemsHtml = order.items.map(function(it) {
|
||||
return '<tr>'
|
||||
+ '<td>' + it.name + '</td>'
|
||||
+ '<td>' + it.price.toFixed(2) + '</td>'
|
||||
+ '<td>' + it.qty + '</td>'
|
||||
+ '<td>' + it.subtotal.toFixed(2) + '</td>'
|
||||
+ '</tr>';
|
||||
}).join('');
|
||||
|
||||
var discountRow = order.discount > 0
|
||||
? '<div class="receipt-row"><span class="receipt-row__label">优惠</span><span class="receipt-row__value" style="color:#d4380d;">-' + order.discount.toFixed(2) + '</span></div>'
|
||||
: '';
|
||||
|
||||
var html = ''
|
||||
+ '<div class="receipt-paper">'
|
||||
/* 食堂抬头 */
|
||||
+ '<div class="receipt-header">'
|
||||
+ '<div class="receipt-name">' + canteenInfo.name + '</div>'
|
||||
+ '<div class="receipt-sub">' + canteenInfo.address + '</div>'
|
||||
+ '<div class="receipt-sub">电话:' + canteenInfo.phone + '</div>'
|
||||
+ '</div>'
|
||||
+ '<div class="receipt-divider receipt-divider--double"></div>'
|
||||
/* 订单信息 */
|
||||
+ '<div class="receipt-info">'
|
||||
+ '<div class="receipt-row"><span class="receipt-row__label">订单号</span><span class="receipt-row__value">' + order.id + '</span></div>'
|
||||
+ '<div class="receipt-row"><span class="receipt-row__label">餐线</span><span class="receipt-row__value">' + order.line + '</span></div>'
|
||||
+ '<div class="receipt-row"><span class="receipt-row__label">收银员</span><span class="receipt-row__value">' + order.cashier + '</span></div>'
|
||||
+ '<div class="receipt-row"><span class="receipt-row__label">就餐时间</span><span class="receipt-row__value">' + order.time + '</span></div>'
|
||||
+ '</div>'
|
||||
+ '<div class="receipt-divider"></div>'
|
||||
/* 消费明细表 */
|
||||
+ '<table class="receipt-table">'
|
||||
+ '<thead><tr><th>餐品</th><th>单价</th><th>份数</th><th>小计</th></tr></thead>'
|
||||
+ '<tbody>' + itemsHtml + '</tbody>'
|
||||
+ '</table>'
|
||||
+ '<div class="receipt-divider"></div>'
|
||||
/* 金额汇总 */
|
||||
+ '<div class="receipt-amount">'
|
||||
+ '<div class="receipt-row"><span class="receipt-row__label">合计</span><span class="receipt-row__value">' + order.total.toFixed(2) + '</span></div>'
|
||||
+ discountRow
|
||||
+ '<div class="receipt-row receipt-amount__payable"><span class="receipt-row__label">应付</span><span>¥' + order.payable.toFixed(2) + '</span></div>'
|
||||
+ '<div class="receipt-row receipt-amount__paid"><span class="receipt-row__label">实付</span><span>¥' + order.paid.toFixed(2) + '</span></div>'
|
||||
+ '</div>'
|
||||
+ '<div class="receipt-divider"></div>'
|
||||
/* 支付信息 */
|
||||
+ '<div class="receipt-info">'
|
||||
+ '<div class="receipt-row"><span class="receipt-row__label">支付方式</span><span class="receipt-row__value">' + order.payMethod + '</span></div>'
|
||||
+ '<div class="receipt-row"><span class="receipt-row__label">餐卡余额</span><span class="receipt-row__value">¥' + order.balance.toFixed(2) + '</span></div>'
|
||||
+ '</div>'
|
||||
+ '<div class="receipt-divider"></div>'
|
||||
/* 营养摄入摘要 */
|
||||
+ '<div class="receipt-nutrition-title">- - - 营养摄入摘要 - - -</div>'
|
||||
+ '<div class="receipt-nutrition-grid">'
|
||||
+ '<div class="nutrition-item"><div class="nutrition-item__label">热量</div><div class="nutrition-item__value">' + order.nutrition.calories + '<small>kcal</small></div></div>'
|
||||
+ '<div class="nutrition-item"><div class="nutrition-item__label">蛋白质</div><div class="nutrition-item__value">' + order.nutrition.protein + '<small>g</small></div></div>'
|
||||
+ '<div class="nutrition-item"><div class="nutrition-item__label">脂肪</div><div class="nutrition-item__value">' + order.nutrition.fat + '<small>g</small></div></div>'
|
||||
+ '<div class="nutrition-item"><div class="nutrition-item__label">碳水</div><div class="nutrition-item__value">' + order.nutrition.carb + '<small>g</small></div></div>'
|
||||
+ '</div>'
|
||||
+ '<div class="receipt-score">'
|
||||
+ '<span class="receipt-score__label">营养得分</span>'
|
||||
+ '<span class="receipt-score__value">' + order.nutrition.score + '</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="receipt-divider"></div>'
|
||||
/* 二维码 */
|
||||
+ '<div class="receipt-qr">'
|
||||
+ getQRCodeSVG()
|
||||
+ '<div class="receipt-qr__text">扫码查看电子小票与营养详情</div>'
|
||||
+ '</div>'
|
||||
+ '<div class="receipt-divider receipt-divider--double"></div>'
|
||||
/* 底部提示 */
|
||||
+ '<div class="receipt-footer">'
|
||||
+ '<div class="receipt-footer__line1">合理膳食 均衡营养</div>'
|
||||
+ '<div class="receipt-footer__line2">谢谢惠顾,欢迎下次光临</div>'
|
||||
+ '</div>'
|
||||
+ '</div>';
|
||||
|
||||
document.getElementById('receiptStage').innerHTML = html;
|
||||
updatePrintBtn();
|
||||
}
|
||||
|
||||
/* 简化版二维码 SVG (21x21 模块,模拟外观) */
|
||||
function getQRCodeSVG() {
|
||||
var matrix = [
|
||||
'111111101010111111100',
|
||||
'100000101011100000110',
|
||||
'101110101110101110110',
|
||||
'101110100101101110010',
|
||||
'101110101101101110000',
|
||||
'100000101001100000110',
|
||||
'111111101010111111100',
|
||||
'000000001101000000000',
|
||||
'101011011001010110010',
|
||||
'011010001100011001010',
|
||||
'101101100110010100100',
|
||||
'011000101010011011010',
|
||||
'101011010011001011100',
|
||||
'000000011001010100010',
|
||||
'111111101100101101000',
|
||||
'100000101011011010110',
|
||||
'101110101010100100100',
|
||||
'101110101101011011010',
|
||||
'101110100110010100110',
|
||||
'100000101011010010010',
|
||||
'111111101101100101100'
|
||||
];
|
||||
var size = 21;
|
||||
var unit = 4;
|
||||
var dim = size * unit;
|
||||
var rects = '<rect x="0" y="0" width="' + dim + '" height="' + dim + '" fill="#fff"/>';
|
||||
for (var r = 0; r < size; r++) {
|
||||
for (var c = 0; c < size; c++) {
|
||||
if (matrix[r].charAt(c) === '1') {
|
||||
rects += '<rect x="' + (c * unit) + '" y="' + (r * unit) + '" width="' + unit + '" height="' + unit + '" fill="#1a1a2e"/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
return '<svg class="receipt-qr__img" viewBox="0 0 ' + dim + ' ' + dim + '" xmlns="http://www.w3.org/2000/svg">' + rects + '</svg>';
|
||||
}
|
||||
|
||||
/* 切换订单 */
|
||||
function selectOrder(orderId) {
|
||||
currentOrderId = orderId;
|
||||
renderOrderList();
|
||||
renderReceipt();
|
||||
}
|
||||
|
||||
/* 打印按钮状态切换 */
|
||||
function updatePrintBtn() {
|
||||
var order = mockOrders.filter(function(o) { return o.id === currentOrderId; })[0];
|
||||
var btn = document.getElementById('printBtn');
|
||||
if (order && order.printed) {
|
||||
btn.className = 'btn btn--primary';
|
||||
btn.innerHTML = '🖨️ 重新打印';
|
||||
} else {
|
||||
btn.className = 'btn btn--success';
|
||||
btn.innerHTML = '🖨️ 打印小票';
|
||||
}
|
||||
}
|
||||
|
||||
/* 打印处理 */
|
||||
function handlePrint() {
|
||||
var order = mockOrders.filter(function(o) { return o.id === currentOrderId; })[0];
|
||||
if (!order) {
|
||||
showToast('请先选择订单', 'warn');
|
||||
return;
|
||||
}
|
||||
order.printed = true;
|
||||
renderOrderList();
|
||||
updatePrintBtn();
|
||||
showToast('订单 ' + order.id + ' 小票打印成功', 'success');
|
||||
}
|
||||
|
||||
/* Toast */
|
||||
function showToast(msg, type) {
|
||||
var el = document.getElementById('toast');
|
||||
el.textContent = msg;
|
||||
el.className = 'toast';
|
||||
if (type === 'success') el.classList.add('toast--success');
|
||||
if (type === 'warn') el.classList.add('toast--warn');
|
||||
el.classList.add('show');
|
||||
clearTimeout(el._timer);
|
||||
el._timer = setTimeout(function() { el.classList.remove('show'); }, 2200);
|
||||
}
|
||||
|
||||
/* 初始化 */
|
||||
renderOrderList();
|
||||
renderReceipt();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,29 +6,181 @@
|
||||
<title>结算设备 - 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
/* 外层视口:全屏深色背景,承载居中 PAD 外壳 */
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #0e1326; color: #fff; width: 1280px; height: 720px; overflow: hidden;
|
||||
background: #05080f;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
/* PAD 设备外壳 */
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: #0e1326;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
/* 顶部导航栏 */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
background: #1a2b4a;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.top-bar__title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
/* 主内容区:三菜单网格 */
|
||||
.main-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 28px;
|
||||
padding: 56px 80px;
|
||||
height: calc(100% - 44px);
|
||||
align-content: center;
|
||||
}
|
||||
/* 菜单卡片 */
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 18px;
|
||||
padding: 36px 24px;
|
||||
background: #1a2b4a;
|
||||
border-radius: 16px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
border-color: rgba(74, 144, 217, 0.3);
|
||||
}
|
||||
/* 禁用卡片(待开发) */
|
||||
.card--disabled {
|
||||
pointer-events: none;
|
||||
background: rgba(26, 43, 74, 0.4);
|
||||
opacity: 0.55;
|
||||
}
|
||||
.card--disabled:hover {
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
border-color: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* 图标圆底 */
|
||||
.card__icon {
|
||||
font-size: 44px;
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
border-radius: 50%;
|
||||
background: rgba(74, 144, 217, 0.12);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.card--disabled .card__icon {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
.card__title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.card--disabled .card__title {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
.card__desc {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.card--disabled .card__desc {
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
/* 右上角状态标签 */
|
||||
.card__status {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
padding: 4px 8px;
|
||||
border-radius: 9px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
.card__status--done {
|
||||
background: rgba(34, 197, 94, 0.18);
|
||||
color: #4ade80;
|
||||
border: 1px solid rgba(34, 197, 94, 0.35);
|
||||
}
|
||||
.card__status--pending {
|
||||
background: rgba(234, 88, 12, 0.18);
|
||||
color: #fb923c;
|
||||
border: 1px solid rgba(234, 88, 12, 0.35);
|
||||
}
|
||||
.top-bar { display: flex; align-items: center; height: 44px; background: #1a2b4a; padding: 0 20px; }
|
||||
.back-btn { font-size: 14px; cursor: pointer; color: rgba(255,255,255,0.7); text-decoration: none; transition: color 0.2s; }
|
||||
.back-btn:hover { color: #fff; }
|
||||
.top-bar__title { flex: 1; text-align: center; font-size: 15px; font-weight: 600; color: rgba(255,255,255,0.85); }
|
||||
.main { display: flex; align-items: center; justify-content: center; height: calc(100% - 44px); }
|
||||
.placeholder { text-align: center; color: rgba(255,255,255,0.3); }
|
||||
.placeholder__icon { font-size: 48px; margin-bottom: 16px; }
|
||||
.placeholder__text { font-size: 14px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="top-bar">
|
||||
<span class="top-bar__title">结算设备</span>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="placeholder">
|
||||
<div class="placeholder__icon">🚧</div>
|
||||
<div class="placeholder__text">结算设备 页面待开发</div>
|
||||
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<div class="top-bar">
|
||||
<span class="top-bar__title">结算设备</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容:三菜单卡片 -->
|
||||
<div class="main-content">
|
||||
|
||||
<!-- 1. 员工登录(待开发) -->
|
||||
<a class="card card--disabled" href="javascript:void(0)">
|
||||
<span class="card__status card__status--pending">待开发</span>
|
||||
<div class="card__icon">🔐</div>
|
||||
<div class="card__title">员工登录</div>
|
||||
<div class="card__desc">人脸识别 / 账号密码登录</div>
|
||||
</a>
|
||||
|
||||
<!-- 2. 结算台(待开发) -->
|
||||
<a class="card card--disabled" href="javascript:void(0)">
|
||||
<span class="card__status card__status--pending">待开发</span>
|
||||
<div class="card__icon">💳</div>
|
||||
<div class="card__title">结算台</div>
|
||||
<div class="card__desc">智能结算与餐卡支付</div>
|
||||
</a>
|
||||
|
||||
<!-- 3. 打印小票(已设计) -->
|
||||
<a class="card" href="02-print-receipt.html">
|
||||
<span class="card__status card__status--done">已设计</span>
|
||||
<div class="card__icon">🖨️</div>
|
||||
<div class="card__title">打印小票</div>
|
||||
<div class="card__desc">餐后结算小票预览与打印</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -264,16 +264,16 @@
|
||||
<div class="card__desc">档口菜品营养分析与称重结算</div>
|
||||
</a>
|
||||
<a class="card" href="checkout-device/index.html">
|
||||
<span class="card__status card__status--none">无需设计</span>
|
||||
<span class="card__status card__status--done">已设计</span>
|
||||
<div class="card__icon">🧾</div>
|
||||
<div class="card__name">结算设备</div>
|
||||
<div class="card__desc">智能结算与支付</div>
|
||||
</a>
|
||||
<a class="card" href="nutrition-score-screen/index.html">
|
||||
<span class="card__status card__status--none">无需设计</span>
|
||||
<span class="card__status card__status--done">已设计</span>
|
||||
<div class="card__icon">📊</div>
|
||||
<div class="card__name">营养得分屏</div>
|
||||
<div class="card__desc">个人营养评分与健康建议</div>
|
||||
<div class="card__desc">实时营养得分看板、用户排行榜与餐品热度</div>
|
||||
</a>
|
||||
<a class="card" href="led-food-display/index.html">
|
||||
<span class="card__status card__status--done">已设计</span>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
@@ -8,244 +8,30 @@
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #030303;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.led-scroll {
|
||||
width: 100vw;
|
||||
.led-display {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.led-scroll::-webkit-scrollbar { display: none; }
|
||||
|
||||
.led-strip {
|
||||
display: flex;
|
||||
width: 4800px;
|
||||
height: 312px;
|
||||
background: #060606;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #333 #060606;
|
||||
}
|
||||
|
||||
/* ---- 格子 ---- */
|
||||
.led-cell {
|
||||
height: 312px;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* LOGO 格 */
|
||||
.led-cell--logo {
|
||||
width: 360px;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
color: #1a1a1a;
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 4px;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* 餐品格 */
|
||||
.led-cell--food {
|
||||
width: 292px;
|
||||
}
|
||||
|
||||
/* ---- 格间分割条 ---- */
|
||||
.led-divider {
|
||||
width: 4px;
|
||||
height: 312px;
|
||||
flex-shrink: 0;
|
||||
background: #0a0a0a;
|
||||
position: relative;
|
||||
}
|
||||
.led-divider::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 1px;
|
||||
top: 16px;
|
||||
bottom: 16px;
|
||||
width: 1px;
|
||||
background: linear-gradient(180deg,
|
||||
transparent 0%,
|
||||
rgba(255,255,255,0.12) 15%,
|
||||
rgba(255,255,255,0.2) 50%,
|
||||
rgba(255,255,255,0.12) 85%,
|
||||
transparent 100%);
|
||||
}
|
||||
|
||||
/* ---- 底部信息卡片 ---- */
|
||||
.info-card {
|
||||
width: calc(100% - 12px);
|
||||
margin-bottom: 8px;
|
||||
background: rgba(255,255,255,0.88);
|
||||
backdrop-filter: blur(6px);
|
||||
border-radius: 10px;
|
||||
padding: 8px 10px 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.info-card__name {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #1a1a1a;
|
||||
letter-spacing: 1.5px;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.info-card__tags {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
.info-card__tag {
|
||||
padding: 2px 8px;
|
||||
border-radius: 20px;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
letter-spacing: 0.3px;
|
||||
white-space: nowrap;
|
||||
background: #4caf50;
|
||||
}
|
||||
|
||||
.info-card__stats {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: baseline;
|
||||
}
|
||||
.info-card__stat {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 1px;
|
||||
}
|
||||
.info-card__stat-num {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #1a1a1a;
|
||||
line-height: 1;
|
||||
}
|
||||
.info-card__stat-unit {
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
color: rgba(0,0,0,0.4);
|
||||
margin-left: 1px;
|
||||
}
|
||||
.info-card__stat-sep {
|
||||
width: 1px;
|
||||
height: 14px;
|
||||
background: rgba(0,0,0,0.1);
|
||||
align-self: center;
|
||||
.led-display img {
|
||||
display: block;
|
||||
height: 50vh;
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="led-scroll">
|
||||
<div class="led-strip" id="ledStrip">
|
||||
<div class="led-cell led-cell--logo">欢迎光临,数字味道</div>
|
||||
</div>
|
||||
<div class="led-display">
|
||||
<img src="img/led-v2.jpg" alt="LED餐品展示">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* 15 道餐品背景:
|
||||
* - img: 真实菜品图 URL(优先)
|
||||
* - bg: 菜品专属渐变色(图片未提供时的默认背景)
|
||||
* 有了真实原图后,将图片放入 img/ 目录,改 img 为本地路径即可生效。
|
||||
*/
|
||||
var foodList = [
|
||||
{ name:'宫保鸡丁', price:6.8, calorie:156, tags:['高蛋白质','富含硒','增强免疫力'],
|
||||
bg:'', img:'img/01-宫保鸡丁/u=1690708677,295588643&fm=253&app=138&f=JPEG.jpg' },
|
||||
{ name:'鱼香肉丝', price:7.2, calorie:142, tags:['高蛋白质','低脂肪','富含铁'],
|
||||
bg:'', img:'img/02-鱼香肉丝/443533a7bdbe4a1d862b93aa3f41defa.webp' },
|
||||
{ name:'番茄炒蛋', price:4.5, calorie:98, tags:['高蛋白质','富含维C','抗氧化'],
|
||||
bg:'', img:'img/03-番茄炒蛋/u=966521940,2056770917&fm=3074&app=3074&f=JPEG.jpg' },
|
||||
{ name:'麻婆豆腐', price:3.8, calorie:85, tags:['高蛋白质','富含钙','低胆固醇'],
|
||||
bg:'', img:'img/04-麻婆豆腐/v2-75bda6021dc7ea0b7ebffea61b37a35d_r.jpg' },
|
||||
{ name:'红烧肉', price:9.5, calorie:242, tags:['高蛋白质','富含铁','补气血'],
|
||||
bg:'', img:'img/05-红烧肉/2f738bd4b31c8701f98edc526f3b863f0708ff1a.webp' },
|
||||
{ name:'清炒时蔬', price:3.0, calorie:45, tags:['低热量','富含纤维','高维生素'],
|
||||
bg:'', img:'img/06-清炒时蔬/06-清炒时蔬.jpg' },
|
||||
{ name:'糖醋排骨', price:8.8, calorie:198, tags:['高蛋白质','富含钙','强筋健骨'],
|
||||
bg:'', img:'img/07-糖醋排骨/e1fe9925bc315c60e16d9b1ef1be4e0348547763.webp' },
|
||||
{ name:'水煮鱼', price:7.5, calorie:128, tags:['高蛋白质','富含Omega3','低脂肪'],
|
||||
bg:'', img:'img/08-水煮鱼/下载.jpg' },
|
||||
{ name:'回锅肉', price:8.0, calorie:185, tags:['高蛋白质','富含铁','增强体力'],
|
||||
bg:'', img:'img/09-回锅肉/u=383043788,2156989392&fm=253&app=138&f=JPEG.jpg' },
|
||||
{ name:'蒜蓉西兰花', price:4.2, calorie:52, tags:['低热量','富含维C','高纤维'],
|
||||
bg:'', img:'img/10-蒜蓉西兰花/8d7cb3525ac74301bc86f074af8cc13b.webp' },
|
||||
{ name:'干煸豆角', price:3.5, calorie:62, tags:['低热量','富含纤维','高蛋白'],
|
||||
bg:'', img:'img/11-干煸豆角/12-酸辣土豆丝.png' },
|
||||
{ name:'酸辣土豆丝', price:2.8, calorie:55, tags:['低脂肪','富含维C','高纤维'],
|
||||
bg:'', img:'img/12-酸辣土豆丝/u=18640018,2947141880&fm=3074&app=3074&f=JPEG.jpg' },
|
||||
{ name:'口水鸡', price:7.8, calorie:168, tags:['高蛋白质','低脂肪','富含硒'],
|
||||
bg:'', img:'img/13-口水鸡/u=873728758,3455945663&fm=253&app=120&f=JPEG.jpg' },
|
||||
{ name:'葱爆牛肉', price:8.5, calorie:178, tags:['高蛋白质','富含铁','增强体力'],
|
||||
bg:'', img:'img/14-葱爆牛肉/0.png' },
|
||||
{ name:'地三鲜', price:3.2, calorie:72, tags:['低热量','富含纤维','高维生素'],
|
||||
bg:'', img:'img/15-地三鲜/42d50814ed454bd8b2fede901de64808.webp' }
|
||||
];
|
||||
|
||||
var strip = document.getElementById('ledStrip');
|
||||
|
||||
foodList.forEach(function(food) {
|
||||
/* 每个餐品格前插入分割条 */
|
||||
var divider = document.createElement('div');
|
||||
divider.className = 'led-divider';
|
||||
strip.appendChild(divider);
|
||||
|
||||
var cell = document.createElement('div');
|
||||
cell.className = 'led-cell led-cell--food';
|
||||
/* 有菜品图用图,没有则用专属渐变色 */
|
||||
cell.style.background = food.img
|
||||
? 'url(' + food.img + ') center/cover no-repeat'
|
||||
: food.bg;
|
||||
|
||||
var tagsHtml = food.tags.map(function(t) {
|
||||
return '<span class="info-card__tag">' + t + '</span>';
|
||||
}).join('');
|
||||
|
||||
cell.innerHTML =
|
||||
'<div class="info-card">' +
|
||||
'<div class="info-card__name">' + food.name + '</div>' +
|
||||
'<div class="info-card__tags">' + tagsHtml + '</div>' +
|
||||
'<div class="info-card__stats">' +
|
||||
'<div class="info-card__stat">' +
|
||||
'<span class="info-card__stat-num">¥' + food.price.toFixed(1) + '</span>' +
|
||||
'<span class="info-card__stat-unit">/100g</span>' +
|
||||
'</div>' +
|
||||
'<div class="info-card__stat-sep"></div>' +
|
||||
'<div class="info-card__stat">' +
|
||||
'<span class="info-card__stat-num">' + food.calorie + '</span>' +
|
||||
'<span class="info-card__stat-unit">kcal/100g</span>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
strip.appendChild(cell);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,29 +6,840 @@
|
||||
<title>营养得分屏 - 蚁熊智能餐养平台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
html, body {
|
||||
font-family: -apple-system, "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
background: #0e1326; color: #fff; width: 1280px; height: 720px; overflow: hidden;
|
||||
color: #fff;
|
||||
}
|
||||
.top-bar { display: flex; align-items: center; height: 44px; background: #1a2b4a; padding: 0 20px; }
|
||||
.back-btn { font-size: 14px; cursor: pointer; color: rgba(255,255,255,0.7); text-decoration: none; transition: color 0.2s; }
|
||||
.back-btn:hover { color: #fff; }
|
||||
.top-bar__title { flex: 1; text-align: center; font-size: 15px; font-weight: 600; color: rgba(255,255,255,0.85); }
|
||||
.main { display: flex; align-items: center; justify-content: center; height: calc(100% - 44px); }
|
||||
.placeholder { text-align: center; color: rgba(255,255,255,0.3); }
|
||||
.placeholder__icon { font-size: 48px; margin-bottom: 16px; }
|
||||
.placeholder__text { font-size: 14px; }
|
||||
body {
|
||||
background: #05080f;
|
||||
min-height: 100vh;
|
||||
min-width: 1280px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* PAD 设备外壳 */
|
||||
.device-frame {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: radial-gradient(ellipse at center, #16305c 0%, #0c1a36 55%, #060d20 100%);
|
||||
border: 1px solid rgba(64, 158, 255, 0.35);
|
||||
box-shadow:
|
||||
0 24px 64px rgba(0, 0, 0, 0.6),
|
||||
0 0 0 1px rgba(64, 158, 255, 0.25),
|
||||
inset 0 0 80px rgba(64, 158, 255, 0.08);
|
||||
}
|
||||
|
||||
/* ============ 顶部信息栏 ============ */
|
||||
.top-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 70px;
|
||||
padding: 0 28px;
|
||||
background: linear-gradient(180deg, rgba(15, 38, 78, 0.85) 0%, rgba(10, 26, 56, 0.4) 100%);
|
||||
border-bottom: 1px solid rgba(64, 158, 255, 0.25);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.top-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
min-width: 220px;
|
||||
}
|
||||
.top-left__date {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.top-left__week {
|
||||
font-size: 12px;
|
||||
color: rgba(150, 200, 255, 0.7);
|
||||
}
|
||||
.top-center {
|
||||
display: flex;
|
||||
gap: 56px;
|
||||
align-items: center;
|
||||
}
|
||||
.kpi {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
.kpi__value {
|
||||
font-size: 38px;
|
||||
font-weight: 700;
|
||||
color: #ff8a3c;
|
||||
line-height: 1;
|
||||
font-family: "DIN Alternate", "Microsoft YaHei", sans-serif;
|
||||
text-shadow: 0 0 18px rgba(255, 138, 60, 0.35);
|
||||
}
|
||||
.kpi__value span.unit {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: rgba(255, 200, 150, 0.85);
|
||||
margin-left: 4px;
|
||||
}
|
||||
.kpi__label {
|
||||
font-size: 12px;
|
||||
color: rgba(180, 210, 255, 0.7);
|
||||
margin-top: 6px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.kpi + .kpi::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -28px;
|
||||
top: 8px;
|
||||
bottom: 8px;
|
||||
width: 1px;
|
||||
background: linear-gradient(180deg, transparent, rgba(64, 158, 255, 0.3), transparent);
|
||||
}
|
||||
.top-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
min-width: 220px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.top-right__city { font-weight: 500; }
|
||||
.top-right__divider {
|
||||
width: 1px;
|
||||
height: 14px;
|
||||
background: rgba(64, 158, 255, 0.3);
|
||||
}
|
||||
.top-right__weather {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.top-right__meal {
|
||||
padding: 3px 10px;
|
||||
background: rgba(255, 138, 60, 0.15);
|
||||
border: 1px solid rgba(255, 138, 60, 0.4);
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
color: #ffb380;
|
||||
}
|
||||
|
||||
/* ============ 实时播报横条(贯穿全屏横向滚动) ============ */
|
||||
.ticker {
|
||||
flex-shrink: 0;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
background: linear-gradient(90deg, rgba(255, 138, 60, 0.18) 0%, rgba(255, 138, 60, 0.04) 30%, rgba(64, 158, 255, 0.04) 100%);
|
||||
border-bottom: 1px solid rgba(64, 158, 255, 0.22);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.ticker__label {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0 16px 0 22px;
|
||||
background: linear-gradient(90deg, rgba(255, 138, 60, 0.35) 0%, rgba(255, 138, 60, 0.1) 100%);
|
||||
border-right: 1px solid rgba(255, 138, 60, 0.3);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #ffd9b0;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.ticker__track {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
mask-image: linear-gradient(90deg, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%);
|
||||
-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 40px, #000 calc(100% - 40px), transparent 100%);
|
||||
}
|
||||
.ticker__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
padding-left: 24px;
|
||||
white-space: nowrap;
|
||||
animation: ticker-scroll 60s linear infinite;
|
||||
}
|
||||
.ticker:hover .ticker__content { animation-play-state: paused; }
|
||||
@keyframes ticker-scroll {
|
||||
0% { transform: translateX(0); }
|
||||
100% { transform: translateX(-50%); }
|
||||
}
|
||||
.ticker__item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13.5px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
.ticker__rank {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #1e3f7a, #122752);
|
||||
border: 1px solid rgba(64, 158, 255, 0.45);
|
||||
color: #8ec5ff;
|
||||
}
|
||||
.ticker__rank.top1 { background: linear-gradient(135deg, #ffd700, #ff9500); color: #fff; border-color: rgba(255,215,0,0.6); }
|
||||
.ticker__rank.top2 { background: linear-gradient(135deg, #d0d5e0, #98a0b0); color: #fff; border-color: rgba(192,197,208,0.6); }
|
||||
.ticker__rank.top3 { background: linear-gradient(135deg, #cd7f32, #8b5a2b); color: #fff; border-color: rgba(205,127,50,0.6); }
|
||||
.ticker__name.anonymous { color: rgba(180, 200, 230, 0.5); font-style: italic; }
|
||||
.ticker__score {
|
||||
color: #ff8a3c;
|
||||
font-weight: 700;
|
||||
font-family: "DIN Alternate", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
.ticker__time {
|
||||
color: rgba(180, 210, 255, 0.55);
|
||||
font-size: 12px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.ticker__sep {
|
||||
color: rgba(64, 158, 255, 0.3);
|
||||
}
|
||||
|
||||
/* ============ 主内容区 ============ */
|
||||
.main {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 1.35fr 1fr;
|
||||
gap: 16px;
|
||||
padding: 14px 22px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* 通用面板 */
|
||||
.panel {
|
||||
background: linear-gradient(180deg, rgba(20, 50, 100, 0.55) 0%, rgba(12, 30, 65, 0.55) 100%);
|
||||
border: 1px solid rgba(64, 158, 255, 0.22);
|
||||
border-radius: 10px;
|
||||
padding: 12px 14px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
.panel__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
letter-spacing: 1px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid rgba(64, 158, 255, 0.18);
|
||||
margin-bottom: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.panel__title::before {
|
||||
content: "";
|
||||
width: 3px;
|
||||
height: 14px;
|
||||
background: linear-gradient(180deg, #ff8a3c, #ffb380);
|
||||
border-radius: 2px;
|
||||
}
|
||||
.panel__title em {
|
||||
font-style: normal;
|
||||
color: rgba(180, 210, 255, 0.6);
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* === 左栏:排行榜(纵向滚动) === */
|
||||
.rank-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
.rank-table thead th {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: rgba(180, 210, 255, 0.65);
|
||||
text-align: left;
|
||||
padding: 4px 8px 6px;
|
||||
border-bottom: 1px solid rgba(64, 158, 255, 0.18);
|
||||
letter-spacing: 0.5px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background: linear-gradient(180deg, rgba(20, 50, 100, 0.95), rgba(15, 38, 78, 0.95));
|
||||
z-index: 2;
|
||||
}
|
||||
.rank-table tbody td {
|
||||
padding: 5px 8px;
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.88);
|
||||
border-bottom: 1px solid rgba(64, 158, 255, 0.06);
|
||||
}
|
||||
.rank-table .col-rank { width: 56px; text-align: center; }
|
||||
.rank-table .col-score { width: 90px; text-align: right; }
|
||||
.rank-table .col-time { width: 100px; text-align: right; }
|
||||
|
||||
.rank-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #1e3f7a, #122752);
|
||||
border: 1px solid rgba(64, 158, 255, 0.45);
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #8ec5ff;
|
||||
}
|
||||
.rank-badge.top1 {
|
||||
background: linear-gradient(135deg, #ffd700, #ff9500);
|
||||
border-color: rgba(255, 215, 0, 0.6);
|
||||
color: #fff;
|
||||
box-shadow: 0 0 8px rgba(255, 215, 0, 0.35);
|
||||
}
|
||||
.rank-badge.top2 {
|
||||
background: linear-gradient(135deg, #d0d5e0, #98a0b0);
|
||||
border-color: rgba(192, 197, 208, 0.6);
|
||||
color: #fff;
|
||||
}
|
||||
.rank-badge.top3 {
|
||||
background: linear-gradient(135deg, #cd7f32, #8b5a2b);
|
||||
border-color: rgba(205, 127, 50, 0.6);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.user-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.avatar {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.avatar.c1 { background: linear-gradient(135deg, #ff7a8a, #ff4d6d); }
|
||||
.avatar.c2 { background: linear-gradient(135deg, #ffb168, #ff8a3c); }
|
||||
.avatar.c3 { background: linear-gradient(135deg, #6ec5ff, #409eff); }
|
||||
.avatar.c4 { background: linear-gradient(135deg, #b07cff, #7c4dff); }
|
||||
.avatar.c5 { background: linear-gradient(135deg, #5cd6a8, #2bb673); }
|
||||
.avatar.c6 { background: linear-gradient(135deg, #ffd166, #f4a623); }
|
||||
.avatar.c-anon {
|
||||
background: rgba(120, 140, 170, 0.25);
|
||||
border: 1px dashed rgba(180, 200, 230, 0.4);
|
||||
color: rgba(180, 200, 230, 0.5);
|
||||
}
|
||||
.user-name { font-size: 13px; }
|
||||
.user-name.anonymous { color: rgba(180, 200, 230, 0.45); font-style: italic; }
|
||||
|
||||
.score-cell {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #ff8a3c;
|
||||
font-family: "DIN Alternate", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
.score-cell.low { color: #ffc183; }
|
||||
.time-cell {
|
||||
color: rgba(200, 220, 255, 0.75);
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-size: 12.5px;
|
||||
}
|
||||
|
||||
/* 纵向循环滚动容器 */
|
||||
.rank-scroller {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
min-height: 0;
|
||||
}
|
||||
.rank-scroller__inner {
|
||||
animation: rank-scroll 40s linear infinite;
|
||||
}
|
||||
.rank-scroller:hover .rank-scroller__inner { animation-play-state: paused; }
|
||||
@keyframes rank-scroll {
|
||||
0% { transform: translateY(0); }
|
||||
100% { transform: translateY(-50%); }
|
||||
}
|
||||
/* 行交替背景 */
|
||||
.rank-scroller__inner tr:nth-child(odd) td { background: rgba(64, 158, 255, 0.04); }
|
||||
.rank-scroller__inner tr:nth-child(even) td { background: rgba(64, 158, 255, 0.01); }
|
||||
|
||||
/* === 右栏 === */
|
||||
.right-col {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto;
|
||||
gap: 14px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* 餐品热度 */
|
||||
.hot-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 9px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hot-item {
|
||||
display: grid;
|
||||
grid-template-columns: 22px 1fr 56px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.hot-item__rank {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: rgba(255, 255, 255, 0.55);
|
||||
text-align: center;
|
||||
font-family: "DIN Alternate", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
.hot-item__rank.top { color: #ff8a3c; }
|
||||
.hot-item__bar-wrap {
|
||||
position: relative;
|
||||
height: 28px;
|
||||
background: rgba(64, 158, 255, 0.08);
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hot-item__bar {
|
||||
position: absolute;
|
||||
left: 0; top: 0; bottom: 0;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 12px;
|
||||
font-size: 12.5px;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 0 12px rgba(0, 0, 0, 0.2) inset;
|
||||
}
|
||||
.hot-item__bar.b1 { background: linear-gradient(90deg, #ff4d6d, #ff7a8a); }
|
||||
.hot-item__bar.b2 { background: linear-gradient(90deg, #ff7a3c, #ffa168); }
|
||||
.hot-item__bar.b3 { background: linear-gradient(90deg, #ffc83c, #ffd968); color: #5b3b00; }
|
||||
.hot-item__bar.b4 { background: linear-gradient(90deg, #7cd166, #a5e58f); color: #1e4d10; }
|
||||
.hot-item__bar.b5 { background: linear-gradient(90deg, #5cc6a8, #8adcc4); color: #0c3a2a; }
|
||||
.hot-item__bar.b6 { background: linear-gradient(90deg, #4cb5d6, #82cee0); color: #0a3040; }
|
||||
.hot-item__count {
|
||||
font-size: 12px;
|
||||
color: rgba(200, 220, 255, 0.7);
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.hot-item__count strong {
|
||||
color: #ffb380;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
font-family: "DIN Alternate", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
|
||||
/* 营养健康宣传图 */
|
||||
.promo {
|
||||
background: linear-gradient(135deg, #d8f3c4 0%, #a8e088 60%, #7ed06d 100%);
|
||||
border-radius: 10px;
|
||||
padding: 12px 16px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 100px;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
box-shadow: 0 6px 18px rgba(126, 208, 109, 0.25);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.promo::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
right: -30px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: radial-gradient(circle, rgba(255, 255, 255, 0.4) 0%, transparent 70%);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.promo__title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #1f4d10;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.promo__subtitle {
|
||||
font-size: 12px;
|
||||
color: #2d5a1c;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.promo__tags {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
.promo__tag {
|
||||
padding: 3px 9px;
|
||||
background: rgba(255, 255, 255, 0.65);
|
||||
border-radius: 12px;
|
||||
font-size: 11px;
|
||||
color: #1f4d10;
|
||||
font-weight: 600;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.promo__plate {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
}
|
||||
.promo__plate .plate {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #e8e8e8 100%);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), inset 0 0 0 6px #f5f5f5;
|
||||
}
|
||||
.promo__plate .food {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.promo__plate .f1 {
|
||||
width: 38px; height: 38px;
|
||||
top: 16px; left: 16px;
|
||||
background: radial-gradient(circle at 30% 30%, #6bbf3a, #3d8b1f);
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||
}
|
||||
.promo__plate .f2 {
|
||||
width: 32px; height: 32px;
|
||||
top: 20px; right: 14px;
|
||||
background: radial-gradient(circle at 30% 30%, #ff6b6b, #c92a2a);
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||
}
|
||||
.promo__plate .f3 {
|
||||
width: 36px; height: 36px;
|
||||
bottom: 12px; left: 28px;
|
||||
background: radial-gradient(circle at 30% 30%, #fffef0, #e8e2c8);
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||
}
|
||||
.promo__plate .f4 {
|
||||
width: 26px; height: 26px;
|
||||
bottom: 20px; right: 20px;
|
||||
background: radial-gradient(circle at 30% 30%, #ff9500, #cc6600);
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
/* ============ 底部品牌 ============ */
|
||||
.footer {
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: rgba(150, 180, 220, 0.5);
|
||||
letter-spacing: 2px;
|
||||
border-top: 1px solid rgba(64, 158, 255, 0.12);
|
||||
background: rgba(8, 18, 40, 0.5);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.footer__brand {
|
||||
color: rgba(180, 210, 255, 0.7);
|
||||
font-weight: 500;
|
||||
}
|
||||
.footer__sep {
|
||||
color: rgba(64, 158, 255, 0.3);
|
||||
}
|
||||
|
||||
.panel { scrollbar-width: none; }
|
||||
.panel::-webkit-scrollbar { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="top-bar">
|
||||
<span class="top-bar__title">营养得分屏</span>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="placeholder">
|
||||
<div class="placeholder__icon">🚧</div>
|
||||
<div class="placeholder__text">营养得分屏 页面待开发</div>
|
||||
<div class="device-frame">
|
||||
|
||||
<!-- ====== 顶部信息栏 ====== -->
|
||||
<div class="top-bar">
|
||||
<div class="top-left">
|
||||
<div class="top-left__date">2026年3月9日 12:32:56</div>
|
||||
<div class="top-left__week">周一 · 第二职工食堂</div>
|
||||
</div>
|
||||
|
||||
<div class="top-center">
|
||||
<div class="kpi">
|
||||
<div class="kpi__value">108<span class="unit">人</span></div>
|
||||
<div class="kpi__label">用餐总人数</div>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="kpi__value">919<span class="unit">千卡</span></div>
|
||||
<div class="kpi__label">人均热量</div>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="kpi__value">80<span class="unit">分</span></div>
|
||||
<div class="kpi__label">人均营养得分</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="top-right">
|
||||
<span class="top-right__city">西安</span>
|
||||
<span class="top-right__weather">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="4.5" fill="#ffd23f"/>
|
||||
<g stroke="#ffd23f" stroke-width="1.8" stroke-linecap="round">
|
||||
<line x1="12" y1="2" x2="12" y2="4.5"/>
|
||||
<line x1="12" y1="19.5" x2="12" y2="22"/>
|
||||
<line x1="2" y1="12" x2="4.5" y2="12"/>
|
||||
<line x1="19.5" y1="12" x2="22" y2="12"/>
|
||||
<line x1="4.5" y1="4.5" x2="6.3" y2="6.3"/>
|
||||
<line x1="17.7" y1="17.7" x2="19.5" y2="19.5"/>
|
||||
<line x1="4.5" y1="19.5" x2="6.3" y2="17.7"/>
|
||||
<line x1="17.7" y1="6.3" x2="19.5" y2="4.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
2-7℃
|
||||
</span>
|
||||
<span class="top-right__divider"></span>
|
||||
<span class="top-right__meal">午餐 10:30-13:30</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 实时播报横条(横向滚动跑马灯,贯穿全屏) ====== -->
|
||||
<div class="ticker">
|
||||
<div class="ticker__label">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="#ff8a3c">
|
||||
<path d="M3 10v4a1 1 0 0 0 1 1h3l4 4V5L7 9H4a1 1 0 0 0-1 1z"/>
|
||||
<path d="M16 8a4 4 0 0 1 0 8" stroke="#ff8a3c" stroke-width="2" fill="none" stroke-linecap="round"/>
|
||||
</svg>
|
||||
实时播报
|
||||
</div>
|
||||
<div class="ticker__track">
|
||||
<div class="ticker__content" id="tickerContent">
|
||||
<!-- 内容由 JS 注入两份实现无缝滚动 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 主内容区 ====== -->
|
||||
<div class="main">
|
||||
|
||||
<!-- ===== 左栏:用户排行榜(纵向循环滚动) ===== -->
|
||||
<div class="panel">
|
||||
<div class="panel__title">
|
||||
用户营养得分排行榜
|
||||
<em>实时滚动 · 已用餐用户</em>
|
||||
</div>
|
||||
<table class="rank-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-rank">排名</th>
|
||||
<th>用户</th>
|
||||
<th class="col-score">健康得分</th>
|
||||
<th class="col-time">下单时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div class="rank-scroller">
|
||||
<table class="rank-table rank-scroller__inner" id="rankTable">
|
||||
<tbody id="rankBody">
|
||||
<!-- 内容由 JS 注入两份实现无缝滚动 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 右栏 ===== -->
|
||||
<div class="right-col">
|
||||
|
||||
<!-- 餐品热度排行榜 -->
|
||||
<div class="panel">
|
||||
<div class="panel__title">
|
||||
餐品热度排行榜
|
||||
<em>今日下单 TOP 6</em>
|
||||
</div>
|
||||
<div class="hot-list">
|
||||
<div class="hot-item">
|
||||
<div class="hot-item__rank top">1</div>
|
||||
<div class="hot-item__bar-wrap">
|
||||
<div class="hot-item__bar b1" style="width: 96%;">酸汤肥牛</div>
|
||||
</div>
|
||||
<div class="hot-item__count"><strong>96</strong>份</div>
|
||||
</div>
|
||||
<div class="hot-item">
|
||||
<div class="hot-item__rank top">2</div>
|
||||
<div class="hot-item__bar-wrap">
|
||||
<div class="hot-item__bar b2" style="width: 82%;">蘑菇炒油菜</div>
|
||||
</div>
|
||||
<div class="hot-item__count"><strong>82</strong>份</div>
|
||||
</div>
|
||||
<div class="hot-item">
|
||||
<div class="hot-item__rank top">3</div>
|
||||
<div class="hot-item__bar-wrap">
|
||||
<div class="hot-item__bar b3" style="width: 71%;">芹菜炒豆干</div>
|
||||
</div>
|
||||
<div class="hot-item__count"><strong>71</strong>份</div>
|
||||
</div>
|
||||
<div class="hot-item">
|
||||
<div class="hot-item__rank">4</div>
|
||||
<div class="hot-item__bar-wrap">
|
||||
<div class="hot-item__bar b4" style="width: 64%;">饱拌心灵美</div>
|
||||
</div>
|
||||
<div class="hot-item__count"><strong>64</strong>份</div>
|
||||
</div>
|
||||
<div class="hot-item">
|
||||
<div class="hot-item__rank">5</div>
|
||||
<div class="hot-item__bar-wrap">
|
||||
<div class="hot-item__bar b5" style="width: 58%;">双色菜花</div>
|
||||
</div>
|
||||
<div class="hot-item__count"><strong>58</strong>份</div>
|
||||
</div>
|
||||
<div class="hot-item">
|
||||
<div class="hot-item__rank">6</div>
|
||||
<div class="hot-item__bar-wrap">
|
||||
<div class="hot-item__bar b6" style="width: 52%;">韭菜炒鸡蛋</div>
|
||||
</div>
|
||||
<div class="hot-item__count"><strong>52</strong>份</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 营养健康宣传 -->
|
||||
<div class="promo">
|
||||
<div class="promo__text">
|
||||
<div class="promo__title">营养健康</div>
|
||||
<div class="promo__subtitle">营养好搭配,饮食有数</div>
|
||||
<div class="promo__tags">
|
||||
<span class="promo__tag">天然</span>
|
||||
<span class="promo__tag">有机</span>
|
||||
<span class="promo__tag">绿色</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="promo__plate">
|
||||
<div class="plate"></div>
|
||||
<div class="food f1"></div>
|
||||
<div class="food f2"></div>
|
||||
<div class="food f3"></div>
|
||||
<div class="food f4"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ====== 底部品牌 ====== -->
|
||||
<div class="footer">
|
||||
<span class="footer__brand">数味智餐</span>
|
||||
<span class="footer__sep">·</span>
|
||||
<span>蚁熊智能餐养平台</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// ============ Mock 数据 ============
|
||||
// 用户排行榜数据(含字段:排名/姓名首字符/姓名/头像色/是否匿名/得分/下单时间)
|
||||
var rankData = [
|
||||
{ rank: 1, initial: '陈', name: '陈*夏', color: 'c1', anon: false, score: 89, time: '12:35:20' },
|
||||
{ rank: 2, initial: '张', name: '张*', color: 'c2', anon: false, score: 88, time: '12:33:18' },
|
||||
{ rank: 3, initial: '?', name: '匿名用户', color: 'c-anon', anon: true, score: 86, time: '12:30:41' },
|
||||
{ rank: 4, initial: '孙', name: '孙*', color: 'c3', anon: false, score: 84, time: '12:28:25' },
|
||||
{ rank: 5, initial: '李', name: '李*欣', color: 'c4', anon: false, score: 83, time: '12:27:02' },
|
||||
{ rank: 6, initial: '王', name: '王*庚', color: 'c5', anon: false, score: 80, time: '12:22:22' },
|
||||
{ rank: 7, initial: '刘', name: '刘*', color: 'c6', anon: false, score: 79, time: '12:19:37' },
|
||||
{ rank: 8, initial: '刘', name: '刘*', color: 'c1', anon: false, score: 77, time: '12:17:58' },
|
||||
{ rank: 9, initial: '王', name: '王*', color: 'c2', anon: false, score: 76, time: '12:15:46' },
|
||||
{ rank: 10, initial: '张', name: '张*', color: 'c4', anon: false, score: 72, time: '12:13:30' },
|
||||
{ rank: 11, initial: '赵', name: '赵*宇', color: 'c3', anon: false, score: 70, time: '12:11:25' },
|
||||
{ rank: 12, initial: '?', name: '匿名用户', color: 'c-anon', anon: true, score: 68, time: '12:09:14' },
|
||||
{ rank: 13, initial: '钱', name: '钱*晨', color: 'c5', anon: false, score: 67, time: '12:07:02' },
|
||||
{ rank: 14, initial: '周', name: '周*飞', color: 'c6', anon: false, score: 65, time: '12:05:58' },
|
||||
{ rank: 15, initial: '吴', name: '吴*娜', color: 'c2', anon: false, score: 64, time: '12:04:10' },
|
||||
{ rank: 16, initial: '郑', name: '郑*豪', color: 'c1', anon: false, score: 62, time: '12:02:33' },
|
||||
{ rank: 17, initial: '冯', name: '冯*瑶', color: 'c4', anon: false, score: 60, time: '12:00:48' },
|
||||
{ rank: 18, initial: '陈', name: '陈*伟', color: 'c3', anon: false, score: 58, time: '11:58:36' },
|
||||
{ rank: 19, initial: '褚', name: '褚*林', color: 'c5', anon: false, score: 56, time: '11:56:20' },
|
||||
{ rank: 20, initial: '卫', name: '卫*萍', color: 'c6', anon: false, score: 54, time: '11:54:05' }
|
||||
];
|
||||
|
||||
// 头像颜色循环(用于实时播报,与排行榜同步)
|
||||
function buildRankBadge(rank) {
|
||||
var cls = '';
|
||||
if (rank === 1) cls = ' top1';
|
||||
else if (rank === 2) cls = ' top2';
|
||||
else if (rank === 3) cls = ' top3';
|
||||
return '<span class="rank-badge' + cls + '">' + rank + '</span>';
|
||||
}
|
||||
function buildAvatar(d) {
|
||||
if (d.anon) {
|
||||
return '<span class="avatar c-anon">?</span>';
|
||||
}
|
||||
return '<span class="avatar ' + d.color + '">' + d.initial + '</span>';
|
||||
}
|
||||
|
||||
// ============ 渲染:排行榜(两份数据无缝衔接) ============
|
||||
function renderRankTable() {
|
||||
var body = document.getElementById('rankBody');
|
||||
var html = '';
|
||||
// 重复两份实现无缝循环
|
||||
for (var dup = 0; dup < 2; dup++) {
|
||||
for (var i = 0; i < rankData.length; i++) {
|
||||
var d = rankData[i];
|
||||
var scoreClass = d.score < 75 ? ' low' : '';
|
||||
var nameClass = d.anon ? ' anonymous' : '';
|
||||
html += '<tr>' +
|
||||
'<td class="col-rank">' + buildRankBadge(d.rank) + '</td>' +
|
||||
'<td><div class="user-cell">' + buildAvatar(d) +
|
||||
'<span class="user-name' + nameClass + '">' + d.name + '</span></div></td>' +
|
||||
'<td class="col-score"><span class="score-cell' + scoreClass + '">' + d.score + '</span></td>' +
|
||||
'<td class="col-time time-cell">' + d.time + '</td>' +
|
||||
'</tr>';
|
||||
}
|
||||
}
|
||||
body.innerHTML = html;
|
||||
}
|
||||
|
||||
// ============ 渲染:实时播报(横向滚动跑马灯) ============
|
||||
function renderTicker() {
|
||||
var ticker = document.getElementById('tickerContent');
|
||||
var html = '';
|
||||
// 重复两份实现无缝循环
|
||||
for (var dup = 0; dup < 2; dup++) {
|
||||
for (var i = 0; i < rankData.length; i++) {
|
||||
var d = rankData[i];
|
||||
var nameClass = d.anon ? ' anonymous' : '';
|
||||
html += '<span class="ticker__item">' +
|
||||
'<span class="ticker__rank' + (d.rank === 1 ? ' top1' : d.rank === 2 ? ' top2' : d.rank === 3 ? ' top3' : '') + '">' + d.rank + '</span>' +
|
||||
'<span class="ticker__name' + nameClass + '">' + d.name + '</span>' +
|
||||
'<span class="ticker__score">' + d.score + '分</span>' +
|
||||
'<span class="ticker__time">' + d.time + '</span>' +
|
||||
'</span>';
|
||||
if (i < rankData.length - 1) {
|
||||
html += '<span class="ticker__sep">·</span>';
|
||||
}
|
||||
}
|
||||
// 两份之间加分隔
|
||||
html += '<span class="ticker__sep">·</span>';
|
||||
}
|
||||
ticker.innerHTML = html;
|
||||
}
|
||||
|
||||
renderRankTable();
|
||||
renderTicker();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user