From b07dd055b484c84bf75f0db2bea3bb6d93341851 Mon Sep 17 00:00:00 2001 From: fengpu <18691763612@163.com> Date: Wed, 12 Aug 2026 08:40:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BB=93=E7=AE=97=E5=8F=B0=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E7=94=A8=E6=88=B7=E5=90=8D=E5=AF=86=E7=A0=81=E7=99=BB?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../checkout-device/01-login.html | 371 +++++++++++++++++- 1 file changed, 359 insertions(+), 12 deletions(-) diff --git a/other-module/canteen-device/checkout-device/01-login.html b/other-module/canteen-device/checkout-device/01-login.html index c3c73d4..e7b796f 100644 --- a/other-module/canteen-device/checkout-device/01-login.html +++ b/other-module/canteen-device/checkout-device/01-login.html @@ -490,6 +490,216 @@ color: #ff6b6b; } .fail-counter.show { display: flex; } + + /* ===== 登录方式切换 Tab ===== */ + .login-tabs { + display: flex; + gap: 4px; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); + flex-shrink: 0; + } + .login-tabs__item { + position: relative; + padding: 10px 18px; + font-size: 14px; + font-weight: 500; + color: rgba(255, 255, 255, 0.45); + background: transparent; + border: none; + cursor: pointer; + transition: color 0.2s; + letter-spacing: 0.5px; + } + .login-tabs__item:hover { color: rgba(255, 255, 255, 0.7); } + .login-tabs__item::after { + content: ""; + position: absolute; + left: 12px; + right: 12px; + bottom: -1px; + height: 2px; + background: transparent; + border-radius: 1px; + transition: background 0.2s; + } + .login-tabs__item.active { + color: #4a90d9; + } + .login-tabs__item.active::after { + background: #4a90d9; + box-shadow: 0 0 8px rgba(74, 144, 217, 0.5); + } + + /* 人脸面板容器(撑满左列) */ + .face-panel { + flex: 1; + display: flex; + flex-direction: column; + gap: 14px; + min-height: 0; + } + /* 账号面板:整体垂直水平居中,不撑满 */ + .account-panel { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 18px; + min-height: 0; + padding: 10px 0; + } + /* hidden 属性兜底:避免被 display:flex 覆盖 */ + .face-panel[hidden], + .account-panel[hidden] { + display: none !important; + } + + /* ===== 账号密码登录表单 ===== */ + .account-form { + width: 340px; + display: flex; + flex-direction: column; + gap: 18px; + background: rgba(26, 43, 74, 0.35); + border: 1px solid rgba(74, 144, 217, 0.18); + border-radius: 14px; + padding: 32px 32px 26px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25); + } + .account-form__header { + text-align: center; + margin-bottom: 4px; + } + .account-form__title { + font-size: 17px; + font-weight: 600; + color: #fff; + letter-spacing: 1px; + } + .account-form__sub { + font-size: 12px; + color: rgba(255, 255, 255, 0.45); + margin-top: 6px; + } + .form-field { + display: flex; + flex-direction: column; + gap: 8px; + } + .form-field__label { + font-size: 12px; + color: rgba(255, 255, 255, 0.6); + letter-spacing: 0.5px; + } + .form-field__input-wrap { + position: relative; + display: flex; + align-items: center; + } + .form-field__icon { + position: absolute; + left: 12px; + font-size: 15px; + opacity: 0.65; + pointer-events: none; + } + .form-field__input { + width: 100%; + height: 42px; + padding: 0 12px 0 38px; + background: rgba(5, 10, 26, 0.55); + border: 1px solid rgba(74, 144, 217, 0.2); + border-radius: 8px; + color: #fff; + font-size: 13px; + transition: all 0.2s; + outline: none; + } + .form-field__input::placeholder { + color: rgba(255, 255, 255, 0.3); + } + .form-field__input:focus { + border-color: #4a90d9; + background: rgba(5, 10, 26, 0.8); + box-shadow: 0 0 0 3px rgba(74, 144, 217, 0.15); + } + .login-submit { + margin-top: 4px; + height: 44px; + background: linear-gradient(135deg, #4a90d9 0%, #2563eb 100%); + border: none; + border-radius: 8px; + color: #fff; + font-size: 14px; + font-weight: 600; + letter-spacing: 4px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + transition: all 0.2s; + box-shadow: 0 4px 14px rgba(74, 144, 217, 0.3); + } + .login-submit:hover { + transform: translateY(-1px); + box-shadow: 0 6px 20px rgba(74, 144, 217, 0.45); + } + .login-submit:active { transform: translateY(0); } + .login-submit:disabled { + opacity: 0.7; + cursor: not-allowed; + transform: none; + } + .login-submit__icon { font-size: 15px; } + .login-hint { + text-align: center; + font-size: 11px; + color: rgba(255, 255, 255, 0.4); + margin-top: -4px; + } + + /* 账号面板底部提示(与表单同宽对齐) */ + .account-tips { + width: 340px; + background: rgba(26, 43, 74, 0.4); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 10px; + padding: 12px 16px 14px; + } + .account-tips__title { + font-size: 12px; + color: rgba(255, 255, 255, 0.55); + font-weight: 500; + letter-spacing: 1px; + margin-bottom: 8px; + display: flex; + align-items: center; + gap: 8px; + } + .account-tips__list { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: 5px; + } + .account-tips__list li { + font-size: 12px; + color: rgba(255, 255, 255, 0.55); + padding-left: 14px; + position: relative; + line-height: 1.6; + } + .account-tips__list li::before { + content: "·"; + position: absolute; + left: 4px; + color: #4a90d9; + font-weight: 700; + } @@ -506,13 +716,16 @@
- +
-
- - 人脸识别登录 + + + + @@ -698,33 +955,117 @@ } } + /* ==================== 登录方式切换 ==================== */ + var tabs = document.querySelectorAll('.login-tabs__item'); + var facePanel = document.getElementById('facePanel'); + var accountPanel = document.getElementById('accountPanel'); + var loginSubmit = document.getElementById('loginSubmit'); + var loginAccount = document.getElementById('loginAccount'); + var loginPassword = document.getElementById('loginPassword'); + /* 当前激活的登录方式:account / face */ + var activeTab = 'account'; + + function switchTab(tabName) { + if (tabName === activeTab) return; + activeTab = tabName; + + tabs.forEach(function(tab) { + var isActive = tab.dataset.tab === tabName; + tab.classList.toggle('active', isActive); + tab.setAttribute('aria-selected', isActive ? 'true' : 'false'); + }); + + if (tabName === 'account') { + facePanel.hidden = true; + accountPanel.hidden = false; + stopRecognition(); + } else { + accountPanel.hidden = true; + facePanel.hidden = false; + startRecognition(); + } + } + + tabs.forEach(function(tab) { + tab.addEventListener('click', function() { + switchTab(tab.dataset.tab); + }); + }); + + /* 账号密码登录提交 */ + loginSubmit.addEventListener('click', function() { + var account = loginAccount.value.trim(); + var password = loginPassword.value; + if (!account) { + showToast('请输入工号', 'warn'); + loginAccount.focus(); + return; + } + if (!password) { + showToast('请输入密码', 'warn'); + loginPassword.focus(); + return; + } + /* 模拟登录成功 */ + loginSubmit.disabled = true; + loginSubmit.innerHTML = ' 登录中...'; + setTimeout(function() { + showToast('登录成功,正在进入系统...', 'success'); + setTimeout(function() { + window.location.href = '02-standby.html'; + }, 800); + }, 600); + }); + + /* 回车键提交 */ + loginPassword.addEventListener('keydown', function(e) { + if (e.key === 'Enter') loginSubmit.click(); + }); + loginAccount.addEventListener('keydown', function(e) { + if (e.key === 'Enter') loginPassword.focus(); + }); + /* ==================== 人脸识别流程模拟 ==================== */ var frame = document.getElementById('cameraFrame'); var statusText = document.getElementById('statusText'); var failCounter = document.getElementById('failCounter'); var failCountEl = document.getElementById('failCount'); var failCount = 3; + /* 保存人脸流程的所有定时器,便于切换 Tab 时清除 */ + var faceTimers = []; + + function clearFaceTimers() { + faceTimers.forEach(function(t) { clearTimeout(t); }); + faceTimers = []; + } + + function stopRecognition() { + clearFaceTimers(); + frame.className = 'camera-frame'; + statusText.textContent = '请面向摄像头进行识别'; + } function startRecognition() { + clearFaceTimers(); /* 阶段 1:提示用户 */ frame.className = 'camera-frame'; statusText.textContent = '请面向摄像头进行识别'; /* 阶段 2:1.5s 后开始扫描 */ - setTimeout(function() { + faceTimers.push(setTimeout(function() { frame.classList.add('scanning'); statusText.textContent = '人脸识别中...'; - }, 1500); + }, 1500)); /* 阶段 3:4s 后识别成功,1.5s 后跳转待机页 */ - setTimeout(function() { + faceTimers.push(setTimeout(function() { frame.classList.remove('scanning'); frame.classList.add('success'); statusText.textContent = '识别成功'; - setTimeout(function() { + faceTimers.push(setTimeout(function() { window.location.href = '02-standby.html'; - }, 1500); - }, 4000); + }, 1500)); + }, 4000)); } /* ==================== Toast ==================== */ @@ -743,8 +1084,14 @@ updateClock(); detectMealType(); setInterval(updateClock, 1000); - /* 自动启动人脸识别模拟 */ - setTimeout(startRecognition, 800); + /* 默认激活「账号密码登录」Tab:HTML 初始即显示账号面板,人脸面板 hidden */ + tabs.forEach(function(tab) { + tab.classList.toggle('active', tab.dataset.tab === 'account'); + }); + accountPanel.hidden = false; + facePanel.hidden = true; + /* 聚焦工号输入框,方便快速登录 */ + setTimeout(function() { loginAccount.focus(); }, 200);