feat: 结算台改为用户名密码登录

This commit is contained in:
fengpu
2026-08-12 08:40:01 +08:00
parent ff48f38dbf
commit b07dd055b4
@@ -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;
}
</style>
</head>
<body>
@@ -506,13 +716,16 @@
<!-- 主内容 -->
<div class="main-area">
<!-- 左列:人脸识别区 -->
<!-- 左列:登录区(人脸/账号密码切换) -->
<div class="camera-col">
<div class="col-label">
<span class="col-label__bar"></span>
人脸识别登录
<!-- 登录方式切换 Tab -->
<div class="login-tabs" role="tablist">
<button class="login-tabs__item" data-tab="account" role="tab" aria-selected="true">账号密码登录</button>
<button class="login-tabs__item" data-tab="face" role="tab" aria-selected="false">人脸识别登录</button>
</div>
<!-- 视图 A:人脸识别面板 -->
<div class="face-panel" id="facePanel" hidden>
<div class="camera-frame" id="cameraFrame">
<div class="camera-frame__bg"></div>
<div class="camera-frame__cross-h"></div>
@@ -555,6 +768,50 @@
<div class="fail-counter" id="failCounter">
&#x26A0;&#xFE0F; 识别失败,今日剩余尝试次数:<span id="failCount">3</span>
</div>
</div>
<!-- 视图 B:账号密码登录面板 -->
<div class="account-panel" id="accountPanel">
<div class="account-form">
<div class="account-form__header">
<div class="account-form__title">收银员登录</div>
<div class="account-form__sub">请输入工号和密码进入结算系统</div>
</div>
<div class="form-field">
<label class="form-field__label">工号</label>
<div class="form-field__input-wrap">
<span class="form-field__icon">&#x1F464;</span>
<input type="text" class="form-field__input" id="loginAccount" placeholder="请输入工号,如 CS001" autocomplete="off">
</div>
</div>
<div class="form-field">
<label class="form-field__label">密码</label>
<div class="form-field__input-wrap">
<span class="form-field__icon">&#x1F512;</span>
<input type="password" class="form-field__input" id="loginPassword" placeholder="请输入登录密码">
</div>
</div>
<button class="login-submit" id="loginSubmit" type="button">
<span class="login-submit__icon">&#x1F511;</span>
登 录
</button>
<div class="login-hint">
<span>&#x1F4DE; 忘记密码请联系食堂管理员</span>
</div>
</div>
<div class="account-tips">
<div class="account-tips__title">
<span class="col-label__bar"></span>
登录提示
</div>
<ul class="account-tips__list">
<li>请使用食堂统一分配的工号登录</li>
<li>连续 5 次密码错误将锁定账号 30 分钟</li>
<li>登录遇到问题可点击右侧「故障报修」</li>
</ul>
</div>
</div>
</div>
<!-- 右列:班次信息 + 操作入口 -->
@@ -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 = '<span class="login-submit__icon">&#x23F3;</span> 登录中...';
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);
</script>
</body>