feat: 结算设备待机页新增副屏人脸识别监控区 + 多页面冗余元素精简

- 02-standby:左下「开始结算」改为副屏人脸识别监控区(三态轮播:成功/光线不足/位置不对),底部入口「小票打印」改为「用餐管理」(占位)
- 03-checkout:删除顶栏「本单应付」、余额信息卡「会员等级」、清空按钮及相关 CSS/JS
- 07-statistics:KPI 对比文案统一为「较昨日午餐」,支付方式柱状图标签语义化
- 08-reconcile:删除差额汇总的「企业补贴优惠」行
- user-02-checkout-sync:删除热量环「略少 76%」提示
- user-04-success:删除二维码「今日已有 1,284 人查看」营销文案
- 同步更新 CHANGELOG、记忆体系文件、CLAUDE.md commit 引用

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fengpu
2026-08-10 14:08:17 +08:00
co-authored by Claude Opus 4.7
parent deb475222c
commit 32bd018c4e
13 changed files with 446 additions and 170 deletions
@@ -142,31 +142,32 @@
min-height: 0;
}
/* 左:大时钟 + 待机动作 */
/* 左:大时钟 + 副屏人脸识别提醒 */
.hero__left {
display: flex;
flex-direction: column;
justify-content: center;
gap: 24px;
padding: 28px 32px;
gap: 18px;
padding: 24px 28px;
background: linear-gradient(135deg, rgba(74, 144, 217, 0.12) 0%, rgba(26, 43, 74, 0.4) 100%);
border: 1px solid rgba(74, 144, 217, 0.2);
border-radius: 18px;
}
/* 时钟区:只显示时分秒 + 餐次标签 */
.clock-block {
display: flex;
flex-direction: column;
gap: 10px;
}
.big-clock {
font-size: 76px;
font-size: 72px;
font-weight: 200;
font-family: Menlo, Consolas, "Courier New", monospace;
line-height: 1;
letter-spacing: 3px;
color: #fff;
}
.big-date {
font-size: 16px;
color: rgba(255, 255, 255, 0.55);
display: flex;
align-items: center;
gap: 10px;
text-shadow: 0 4px 24px rgba(74, 144, 217, 0.4);
}
.meal-tag-large {
display: inline-flex;
@@ -176,6 +177,7 @@
border-radius: 16px;
font-size: 13px;
font-weight: 600;
align-self: flex-start;
}
.meal-tag-large--lunch {
background: rgba(37, 99, 235, 0.18);
@@ -183,58 +185,173 @@
border: 1px solid rgba(37, 99, 235, 0.35);
}
/* 开始结算按钮 */
.start-checkout {
/* 副屏人脸识别提醒区(收银员视角,用于提示顾客人脸识别状态) */
.face-monitor {
padding: 18px 20px;
background: rgba(0, 0, 0, 0.25);
border: 1.5px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
transition: border-color 0.4s, box-shadow 0.4s;
}
/* 三态:border + 阴影联动 */
.face-monitor--success {
border-color: rgba(74, 222, 128, 0.6);
box-shadow: 0 0 18px rgba(74, 222, 128, 0.22), inset 0 0 0 1px rgba(74, 222, 128, 0.18);
}
.face-monitor--warning {
border-color: rgba(251, 191, 36, 0.6);
box-shadow: 0 0 18px rgba(251, 191, 36, 0.22), inset 0 0 0 1px rgba(251, 191, 36, 0.18);
animation: faceWarnBlink 1.4s ease-in-out infinite;
}
.face-monitor--info {
border-color: rgba(96, 165, 250, 0.55);
box-shadow: 0 0 18px rgba(96, 165, 250, 0.18), inset 0 0 0 1px rgba(96, 165, 250, 0.16);
}
@keyframes faceWarnBlink {
0%, 100% { opacity: 1; }
50% { opacity: 0.72; }
}
/* 监控标题行 */
.face-monitor__head {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 14px;
}
.face-monitor__title {
font-size: 14px;
color: rgba(255, 255, 255, 0.75);
letter-spacing: 0.5px;
display: flex;
align-items: center;
justify-content: center;
gap: 14px;
padding: 22px 28px;
background: linear-gradient(135deg, #4a90d9, #3a7bc8);
border: none;
border-radius: 14px;
cursor: pointer;
transition: all 0.25s;
text-decoration: none;
box-shadow: 0 8px 24px rgba(74, 144, 217, 0.3);
gap: 8px;
font-weight: 600;
}
.face-monitor__live {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: rgba(255, 255, 255, 0.55);
}
.face-monitor__live::before {
content: "";
width: 7px;
height: 7px;
border-radius: 50%;
background: #ef4444;
box-shadow: 0 0 6px #ef4444;
animation: liveBlink 1.2s infinite;
}
@keyframes liveBlink {
0%, 100% { opacity: 1; }
50% { opacity: 0.35; }
}
/* 监控主体:左模拟副屏画面 + 右文案 */
.face-monitor__body {
display: grid;
grid-template-columns: 200px 1fr;
gap: 20px;
align-items: center;
}
/* 模拟副屏画面(黑色摄像头视角) */
.face-preview {
position: relative;
width: 200px;
height: 140px;
background: linear-gradient(180deg, #0a0e1a 0%, #14182a 100%);
border-radius: 10px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.08);
}
.start-checkout:hover {
transform: translateY(-2px);
box-shadow: 0 12px 32px rgba(74, 144, 217, 0.45);
/* 人形剪影 */
.face-preview__silhouette {
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
width: 110px;
height: 120px;
background: radial-gradient(circle at 50% 25%, rgba(255,255,255,0.12) 0%, rgba(255,255,255,0.04) 30%, transparent 60%);
border-radius: 50% 50% 20% 20% / 60% 60% 30% 30%;
}
.start-checkout:active { transform: scale(0.99); }
.start-checkout__icon {
font-size: 32px;
/* 人脸检测框(状态色虚线) */
.face-preview__box {
position: absolute;
left: 50%;
top: 18%;
transform: translateX(-50%);
width: 74px;
height: 82px;
border: 1.5px dashed rgba(255, 255, 255, 0.4);
border-radius: 6px;
transition: border-color 0.3s;
}
.start-checkout__text {
text-align: left;
.face-preview__box--success { border-color: #4ade80; box-shadow: 0 0 8px rgba(74, 222, 128, 0.5); }
.face-preview__box--warning { border-color: #fbbf24; box-shadow: 0 0 8px rgba(251, 191, 36, 0.5); }
.face-preview__box--info { border-color: #60a5fa; box-shadow: 0 0 8px rgba(96, 165, 250, 0.4); }
/* 检测框四角强调 */
.face-preview__corner {
position: absolute;
width: 10px;
height: 10px;
border: 2px solid currentColor;
}
.face-preview__corner--tl { top: -1px; left: -1px; border-right: none; border-bottom: none; border-top-left-radius: 3px; }
.face-preview__corner--tr { top: -1px; right: -1px; border-left: none; border-bottom: none; border-top-right-radius: 3px; }
.face-preview__corner--bl { bottom: -1px; left: -1px; border-right: none; border-top: none; border-bottom-left-radius: 3px; }
.face-preview__corner--br { bottom: -1px; right: -1px; border-left: none; border-top: none; border-bottom-right-radius: 3px; }
/* 扫描线(位置不对状态时上下扫动) */
.face-preview__scan {
position: absolute;
left: 8%;
right: 8%;
height: 1.5px;
background: linear-gradient(90deg, transparent, rgba(96, 165, 250, 0.8), transparent);
top: 20%;
animation: scanMove 2.2s linear infinite;
}
@keyframes scanMove {
0% { top: 18%; opacity: 0.9; }
50% { top: 70%; opacity: 0.9; }
100% { top: 18%; opacity: 0.9; }
}
/* 右侧文案区 */
.face-info {
display: flex;
flex-direction: column;
gap: 2px;
gap: 10px;
min-width: 0;
}
.start-checkout__title {
font-size: 20px;
.face-info__status {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 14px;
border-radius: 14px;
font-size: 13px;
font-weight: 700;
align-self: flex-start;
}
.face-info__status--success { background: rgba(74, 222, 128, 0.18); color: #4ade80; border: 1px solid rgba(74, 222, 128, 0.4); }
.face-info__status--warning { background: rgba(251, 191, 36, 0.18); color: #fbbf24; border: 1px solid rgba(251, 191, 36, 0.4); }
.face-info__status--info { background: rgba(96, 165, 250, 0.18); color: #60a5fa; border: 1px solid rgba(96, 165, 250, 0.4); }
.face-info__user {
font-size: 26px;
font-weight: 700;
color: #fff;
line-height: 1.2;
}
.start-checkout__desc {
font-size: 12px;
color: rgba(255, 255, 255, 0.8);
}
/* 呼吸灯 */
.start-checkout::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(45deg, transparent 30%, rgba(255,255,255,0.15) 50%, transparent 70%);
transform: translateX(-100%);
animation: shimmer 2.5s ease-in-out infinite;
}
@keyframes shimmer {
0%, 100% { transform: translateX(-100%); }
50% { transform: translateX(100%); }
.face-info__sub {
font-size: 14px;
color: rgba(255, 255, 255, 0.6);
line-height: 1.5;
}
/* 右:今日数据预览 */
@@ -385,23 +502,43 @@
<!-- 中央核心动作区 -->
<div class="hero">
<!-- 左:大时钟 + 开始结算 -->
<!-- 左:大时钟 + 副屏人脸识别提醒 -->
<div class="hero__left">
<div>
<!-- 时钟区:只显示时分秒 + 餐次标签(年月日已由右上角 topMeta 展示) -->
<div class="clock-block">
<div class="big-clock" id="bigClock">12:30:45</div>
<div class="big-date" id="bigDate">
2026-08-06 周四
<span class="meal-tag-large meal-tag-large--lunch" id="mealTag">&#x1F96A; 午餐时段</span>
<span class="meal-tag-large meal-tag-large--lunch" id="mealTag">&#x1F96A; 午餐时段</span>
</div>
<!-- 副屏人脸识别提醒区(收银员用于判断是否需要提示顾客调整站位/补光) -->
<div class="face-monitor face-monitor--success" id="faceMonitor">
<div class="face-monitor__head">
<div class="face-monitor__title">&#x1F4F7; 副屏人脸识别</div>
<div class="face-monitor__live">实时</div>
</div>
<div class="face-monitor__body">
<!-- 模拟副屏画面:人形剪影 + 检测框 -->
<div class="face-preview">
<div class="face-preview__silhouette"></div>
<div class="face-preview__box face-preview__box--success" id="faceBox">
<span class="face-preview__corner face-preview__corner--tl"></span>
<span class="face-preview__corner face-preview__corner--tr"></span>
<span class="face-preview__corner face-preview__corner--bl"></span>
<span class="face-preview__corner face-preview__corner--br"></span>
</div>
<!-- 扫描线仅在"位置不对"时显示 -->
<div class="face-preview__scan" id="faceScan" style="display:none;"></div>
</div>
<!-- 右侧文案 -->
<div class="face-info">
<span class="face-info__status face-info__status--success" id="faceStatus">&#x2705; 识别成功</span>
<div class="face-info__user" id="faceUser">张*明</div>
<div class="face-info__sub" id="faceSub">会员金牌 LV5 · 工号 EMP002346</div>
</div>
</div>
</div>
<a class="start-checkout" href="03-checkout.html">
<span class="start-checkout__icon">&#x1F6CD;&#xFE0F;</span>
<span class="start-checkout__text">
<span class="start-checkout__title">开始结算</span>
<span class="start-checkout__desc">顾客取餐完成,点击进入结算流程</span>
</span>
</a>
</div>
<!-- 右:今日数据预览 -->
@@ -448,11 +585,11 @@
<div class="entry-card__desc">今日数据可视化</div>
</div>
</a>
<a class="entry-card" href="09-receipt-preview.html">
<div class="entry-card__icon entry-card__icon--gold">&#x1F5A8;&#xFE0F;</div>
<a class="entry-card" href="javascript:void(0)" onclick="alert('用餐管理功能待开发')">
<div class="entry-card__icon entry-card__icon--gold">&#x1F37D;&#xFE0F;</div>
<div class="entry-card__text">
<div class="entry-card__title">小票打印</div>
<div class="entry-card__desc">补打/重打订单小票</div>
<div class="entry-card__title">用餐管理</div>
<div class="entry-card__desc">用餐记录/餐次管理</div>
</div>
</a>
<a class="entry-card" href="javascript:void(0)" onclick="alert('设置功能待开发')">
@@ -469,26 +606,117 @@
</div>
<script>
/* 实时时钟 */
/* ============ 实时时钟(只显示时分秒,年月日由 topMeta 展示) ============ */
function updateClock() {
var now = new Date();
var hh = String(now.getHours()).padStart(2, '0');
var mm = String(now.getMinutes()).padStart(2, '0');
var ss = String(now.getSeconds()).padStart(2, '0');
var timeStr = hh + ':' + mm + ':' + ss;
document.getElementById('bigClock').textContent = hh + ':' + mm + ':' + ss;
/* 右上角元信息:年月日 + 周几 */
var year = now.getFullYear();
var month = String(now.getMonth() + 1).padStart(2, '0');
var date = String(now.getDate()).padStart(2, '0');
var weekDay = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][now.getDay()];
var dateStr = year + '-' + month + '-' + date + ' ' + weekDay;
document.getElementById('topMeta').textContent = year + '-' + month + '-' + date + ' ' + weekDay;
document.getElementById('bigClock').textContent = timeStr;
document.getElementById('bigDate').firstChild.textContent = ' ' + dateStr + ' ';
document.getElementById('topMeta').textContent = dateStr;
/* 自动判断餐次(根据当前小时切换标签文案/配色) */
var hour = now.getHours();
var mealTag = document.getElementById('mealTag');
if (hour >= 6 && hour < 10) {
mealTag.style.background = 'rgba(250,140,22,0.18)';
mealTag.style.color = '#fb923c';
mealTag.style.borderColor = 'rgba(250,140,22,0.35)';
mealTag.innerHTML = '&#x1F305; 早餐时段';
} else if (hour >= 10 && hour < 14) {
mealTag.style.background = '';
mealTag.style.color = '';
mealTag.style.borderColor = '';
mealTag.innerHTML = '&#x1F96A; 午餐时段';
} else if (hour >= 16 && hour < 21) {
mealTag.style.background = 'rgba(34,197,94,0.18)';
mealTag.style.color = '#4ade80';
mealTag.style.borderColor = 'rgba(34,197,94,0.35)';
mealTag.innerHTML = '&#x1F319; 晚餐时段';
} else {
mealTag.style.background = '';
mealTag.style.color = '';
mealTag.style.borderColor = '';
mealTag.innerHTML = '&#x1F31F; 欢迎光临';
}
}
updateClock();
setInterval(updateClock, 1000);
/* ============ 副屏人脸识别状态三态轮播(演示) ============
三态轮播用于在原型中展示收银员需要识别的三种提醒场景:
success: 识别成功 - 显示用户信息,收银员可引导支付
warning: 光线不足 - 提醒顾客补光
info: 位置不对 - 提醒顾客正对摄像头
后端真实场景下应根据副屏识别结果事件触发状态切换,而非轮播。
*/
var FACE_STATES = [
{
key: 'success',
monitorCls: 'face-monitor--success',
boxCls: 'face-preview__box--success',
statusCls: 'face-info__status--success',
statusHtml: '&#x2705; 识别成功',
user: '张*明',
sub: '会员金牌 LV5 · 工号 EMP002346',
showScan: false
},
{
key: 'warning',
monitorCls: 'face-monitor--warning',
boxCls: 'face-preview__box--warning',
statusCls: 'face-info__status--warning',
statusHtml: '&#x1F4A1; 光线不足',
user: '— · —',
sub: '环境亮度低于识别阈值,请补光',
showScan: false
},
{
key: 'info',
monitorCls: 'face-monitor--info',
boxCls: 'face-preview__box--info',
statusCls: 'face-info__status--info',
statusHtml: '&#x1F3AF; 位置不对',
user: '未检测到人脸',
sub: '请顾客正对摄像头并保持 50-80cm 距离',
showScan: true
}
];
var faceIdx = 0;
function applyFaceState(state) {
var monitor = document.getElementById('faceMonitor');
var box = document.getElementById('faceBox');
var status = document.getElementById('faceStatus');
var user = document.getElementById('faceUser');
var sub = document.getElementById('faceSub');
var scan = document.getElementById('faceScan');
/* 清除原三态修饰类 */
monitor.className = 'face-monitor ' + state.monitorCls;
box.className = 'face-preview__box ' + state.boxCls;
status.className = 'face-info__status ' + state.statusCls;
status.innerHTML = state.statusHtml;
user.textContent = state.user;
sub.textContent = state.sub;
scan.style.display = state.showScan ? 'block' : 'none';
}
function rotateFaceState() {
applyFaceState(FACE_STATES[faceIdx]);
faceIdx = (faceIdx + 1) % FACE_STATES.length;
}
/* 初始展示第一态,4 秒后开始轮播 */
rotateFaceState();
setInterval(rotateFaceState, 4000);
</script>
</body>
@@ -896,15 +896,6 @@
color: #0AC4A8;
font-weight: 800;
}
.balance-info__level {
padding: 3px 10px;
background: linear-gradient(135deg, rgba(251, 191, 36, 0.25), rgba(251, 146, 60, 0.18));
border: 1px solid rgba(251, 191, 36, 0.5);
border-radius: 10px;
font-size: 11px;
color: #fbbf24;
font-weight: 700;
}
.balance-info__tip {
margin-top: 6px;
padding: 5px 8px;
@@ -1155,10 +1146,6 @@
<span>账户余额</span>
<strong id="topBalance">&#xFFE5;128.50</strong>
</div>
<div class="user-bar__meta-item">
<span>本单应付</span>
<strong id="topPayable">&#xFFE5;64.40</strong>
</div>
</div>
</div>
@@ -1176,9 +1163,6 @@
<a class="header-btn header-btn--primary" href="08-reconcile.html">
&#x270F;&#xFE0F; 补齐明细
</a>
<a class="header-btn" href="javascript:void(0)" onclick="clearAll()">
&#x1F5D1;&#xFE0F; 清空
</a>
</div>
</div>
@@ -1420,7 +1404,6 @@
<!-- 余额支付信息卡 -->
<div class="balance-info" id="balanceInfo">
<div class="balance-info__row">
<span class="balance-info__label">&#x1F451; 会员等级 <span class="balance-info__level">金牌会员 LV5</span></span>
<span class="balance-info__label">&#x1F4B0; 账户余额 <span class="balance-info__value balance-info__value--highlight" id="balanceAvail">&#xFFE5;128.50</span></span>
</div>
<div class="balance-info__row">
@@ -1499,7 +1482,6 @@
var ORDER_PAYABLE = ORDER_TOTAL - ORDER_DISCOUNT; /* 64.40 */
var COUPON_VALUE = 10.00; /* 代金券面值 */
var USER_BALANCE = 128.50; /* 会员账户余额 */
var USER_LEVEL = '金牌会员 LV5';
/* 全局状态:currentPay 为当前支付方式 Tab;couponApplied 为是否已核销代金券;
mixedMode 为混合支付状态(null=未混合 | 'bl-online' | 'bl-cash' | 'cash-online');
@@ -1684,9 +1666,6 @@
btnAmount.innerHTML = '&#xFFE5;' + amountToShow.toFixed(2);
btn.innerHTML = prefix + '<span id="btnAmount">&#xFFE5;' + amountToShow.toFixed(2) + '</span>';
/* 同步顶部应付金额 */
document.getElementById('topPayable').innerHTML = '&#xFFE5;' + effPayable.toFixed(2);
}
/* 刷新余额信息卡(余额支付 Tab 下显示;混合支付进行中也保留,仅切换提示文案与按钮选中态) */
@@ -1949,16 +1928,6 @@
}, 1200);
}
/* 清空订单 */
function clearAll() {
if (confirm('确定清空当前订单所有商品吗?')) {
document.getElementById('itemsList').innerHTML =
'<div class="empty-state"><div class="empty-state__icon">&#x1F6CD;&#xFE0F;</div>'
+ '<div class="empty-state__text">订单已清空,等待顾客重新取餐</div></div>';
document.getElementById('itemCount').textContent = '0 件';
}
}
/* Toast 提示 */
function showToast(msg, type) {
var el = document.getElementById('toast');
@@ -1978,8 +1947,8 @@
- low-balance 余额不足(USER_BALANCE=20.00),走混合支付,演示余额+在线/现金补差
代金券预载为独立开关,可叠加在任一场景上。 */
var DEMO_SCENES = {
'normal': { balance: 128.50, level: '金牌会员 LV5' },
'low-balance': { balance: 20.00, level: '金牌会员 LV5' }
'normal': { balance: 128.50 },
'low-balance': { balance: 20.00 }
};
var currentScene = 'normal';
var couponPreset = false; /* 代金券预载开关 */
@@ -749,7 +749,7 @@
</div>
<div class="kpi-card__compare">
<span class="compare-up">&#x2197; 8.3%</span>
<span>已结 80 / 进行 16</span>
<span>较昨日午餐</span>
</div>
</div>
@@ -761,7 +761,7 @@
</div>
<div class="kpi-card__compare">
<span class="compare-down">&#x2198; 0.3%</span>
<span>退款率 1.8%</span>
<span>较昨日午餐</span>
</div>
</div>
@@ -835,17 +835,17 @@
<div class="bars__item">
<span class="bars__value">&#xFFE5;732.06</span>
<div class="bars__bar bars__bar--face" style="height:43%;"></div>
<span class="bars__label">&#x1F464; 刷脸</span>
<span class="bars__label">&#x1F464; 余额支付</span>
</div>
<div class="bars__item">
<span class="bars__value">&#xFFE5;313.74</span>
<div class="bars__bar bars__bar--cash" style="height:18%;"></div>
<span class="bars__label">&#x1F4B6; 现金</span>
<span class="bars__label">&#x1F4B6; 现金支付</span>
</div>
<div class="bars__item">
<span class="bars__value">&#xFFE5;209.16</span>
<div class="bars__bar bars__bar--coupon" style="height:12%;"></div>
<span class="bars__label">&#x1F3AB; 餐券</span>
<span class="bars__label">&#x1F3AB; 餐券抵扣</span>
</div>
</div>
</div>
@@ -775,8 +775,6 @@
<span class="compare-row__value" id="newAmount">&#xFFE5;46.60</span>
</div>
<div class="compare-row" style="border-top:1px solid rgba(255,255,255,0.1);margin-top:6px;padding-top:10px;">
<span class="compare-row__label">企业补贴优惠</span>
<span class="compare-row__value" style="color:#4ade80;">-&#xFFE5;5.00</span>
</div>
<div class="compare-row compare-row--delta" id="deltaRow">
<span class="compare-row__label">应付金额</span>
@@ -1,5 +1,60 @@
# 结算设备 CHANGELOG
## 2026-08-10 | 待机页(02)新增副屏人脸识别监控区 + 入口改名
### 业务背景
`02-standby.html` 待机页左下角的「开始结算」按钮是收银员主动进入结算流程的入口,但实际业务中:
1. **结算入口已由副屏人脸识别驱动**:顾客取餐后站立到副屏前会被自动识别,收银员屏 03-checkout 自动加载订单。手动「开始结算」按钮与该流程重复,且容易让收银员误以为需要主动触发。
2. **收银员无法判断副屏识别状态**:副屏识别成功率受光线/站位影响,但收银员屏没有对应的实时反馈区,无法主动提示顾客调整站位或补光。
### 变更
- **删除「开始结算」按钮区**,左下区域改为「副屏人脸识别监控区」
- **监控区三态轮播演示**(对应真实业务中的三种识别状态):
- `success` 识别成功:绿色边框 + ✅ 徽标 + 脱敏用户名 + 会员等级/工号
- `warning` 光线不足:黄色边框 + 💡 徽标 + 「环境亮度低于识别阈值,请补光」
- `info` 位置不对:蓝色边框 + 🎯 徽标 + 「请顾客正对摄像头并保持 50-80cm 距离」+ 扫描线动画
- **模拟副屏画面**:200×140px 黑色摄像头视角块,含人形剪影 + 检测框(四角强调 + 状态色虚线) + LIVE 实时指示
- **时钟区精简**:年月日已由右上角 topMeta 承担,时钟区只保留「时分秒 + 餐次标签」,餐次标签按当前小时自动切换(早餐/午餐/晚餐/欢迎光临)
- **底部入口改名**:原「🖨️ 小票打印 - 补打/重打订单小票」改为「🍽️ 用餐管理 - 用餐记录/餐次管理」(功能待开发,占位 `javascript:void(0)`)
### 技术实现
- 监控区采用 `face-monitor--{success|warning|info}` 三态修饰符,通过 `border-color` + `box-shadow` 联动 + `animation: faceWarnBlink` 实现 warning 态闪烁
- 模拟副屏画面采用纯 CSS 实现:`radial-gradient` 模拟人形剪影、`border-dashed` + 四角 `.face-preview__corner` 强调检测框、`@keyframes scanMove` 实现扫描线垂直循环
- 轮播逻辑:4 秒切换一次状态,后端真实场景下应替换为副屏识别事件驱动
### 不变更
- 右上角 topMeta(年月日 + 周几)、今日数据预览(右栏 KPI 卡片)、底部其他入口卡片(订单管理/对账管理/设置)保持不变
- 时钟更新逻辑(每秒 setInterval)与 topMeta 同步逻辑保持不变
---
## 2026-08-10 | 多页面冗余元素精简(03 / 07 / 08 / user-02 / user-04)
### 业务背景
结算设备多个页面在前期原型迭代过程中积累了一些「demo 占位文案 / 重复信息 / 与新业务模型不符的冗余字段」,需要在新业务模型(用户类型三态体系、支付方式六态体系)落地后统一清理,避免视觉噪声与信息歧义。
### 变更清单
- **`03-checkout.html` 收银页**:
- 删除顶栏「本单应付」字段(应付金额已由右栏底部按钮统一展示,顶栏重复显示)
- 删除余额信息卡的「👑 会员等级 - 金牌会员 LV5」行(用户身份徽标已由 `user-type` 三态徽标承担,等级信息冗余)
- 删除顶部操作按钮组的「🗑️ 清空」按钮(支付前不应允许整体清空订单,业务上属于危险操作)
- 同步删除相关 CSS(`.balance-info__level`)、JS 变量(`USER_LEVEL``topPayable` 同步逻辑)、`clearAll()` 函数、`DEMO_SCENES.normal/low-balance.level` 字段
- **`07-statistics.html` 统计页**:
- KPI 卡片对比文案统一改为「较昨日午餐」(原为「已结 80 / 进行 16」「退款率 1.8%」等不统一的 demo 文案)
- 支付方式柱状图标签语义化:「刷脸」→「余额支付」、「现金」→「现金支付」、「餐券」→「餐券抵扣」(对齐 03-checkout 的支付方式体系)
- **`08-reconcile.html` 补齐明细页**:
- 删除右列差额汇总的「企业补贴优惠 -¥5.00」一行(企业补贴模型已不适用,且与「补齐未识别」业务路径无关)
- **`user-02-checkout-sync.html` 用户副屏取餐同步页**:
- 删除热量环中央的「略少 76%」提示文字(占位文案无实际业务含义,且与下方 `/ 950 kcal` 信息冗余)
- **`user-04-success.html` 用户副屏支付成功页**:
- 删除二维码引导区的「🔥 今日已有 1,284 人查看」营销文案(原型 demo 文案,与真实业务数据无关)
### 不变更
- 各页面的核心业务结构、支付流程、URL 参数驱动逻辑保持不变
- 用户类型徽标体系、支付方式徽标体系保持不变
---
## 2026-08-10 | 订单列表(05)+订单详情(06)增加用户类型展示
### 业务背景
@@ -997,7 +997,6 @@
<div class="calorie-ring__center">
<div class="calorie-ring__value">720</div>
<div class="calorie-ring__unit">/ 950 kcal</div>
<div class="calorie-ring__hint">略少 76%</div>
</div>
</div>
@@ -559,7 +559,6 @@
<div class="qr-guide__text">
<div class="qr-guide__title">&#x1F4F1; 扫码查看详细营养报告</div>
<div class="qr-guide__sub">小程序内可查看每日营养摄入趋势、健康建议、餐品推荐</div>
<span class="qr-guide__tag">&#x1F525; 今日已有 1,284 人查看</span>
</div>
</div>
</div>