fix: 修复登录重复创建会话 + 备注输入框不可交互

- login.js 增加防重复提交锁,请求期间禁用按钮
- Manager.Create 增加幂等检查,同用户同IP同UA 10秒内复用已有会话
- 移除当前设备备注输入框的 readonly 限制,改为 data-current 标记
- 修复 readonly 状态下输入框完全透明无法点击的问题
This commit is contained in:
2026-05-31 00:28:00 +08:00
parent 47ef3f2a99
commit d5d33c3ace
4 changed files with 68 additions and 14 deletions

View File

@ -125,7 +125,7 @@
<span class="session-time">最后活动 {{.LastAccess.Format "2006-01-02 15:04"}}</span>
</div>
<div class="session-remark-row">
<input type="text" class="session-remark-input" value="{{.Remark}}" placeholder="添加备注(如 我的笔记本)" maxlength="32" data-sid="{{.ID}}" {{if .IsCurrent}}readonly{{end}}>
<input type="text" class="session-remark-input" value="{{.Remark}}" placeholder="添加备注(如 我的笔记本)" maxlength="32" data-sid="{{.ID}}" data-current="{{.IsCurrent}}">
</div>
</div>
<div class="session-action">

View File

@ -690,15 +690,15 @@ body {
background: #fff;
}
.session-remark-input[readonly] {
background: transparent;
border-color: transparent;
cursor: default;
.session-remark-input[data-current="true"] {
background: rgba(46, 204, 113, .03);
border-color: rgba(46, 204, 113, .2);
}
.session-remark-input[readonly]:focus {
box-shadow: none;
border-color: transparent;
.session-remark-input[data-current="true"]:focus {
border-color: var(--color-accent);
box-shadow: 0 0 0 3px rgba(52, 152, 219, .15);
background: #fff;
}
.session-action {

View File

@ -55,7 +55,14 @@
doLogin(email, password);
});
var loginInProgress = false;
function doLogin(email, password) {
if (loginInProgress) return;
loginInProgress = true;
submitBtn.disabled = true;
submitBtn.textContent = '登录中...';
var xhr = new XMLHttpRequest();
xhr.open('POST', '/api/auth/login', true);
xhr.setRequestHeader('Content-Type', 'application/json');
@ -65,7 +72,9 @@
try { resp = JSON.parse(xhr.responseText); } catch (err) { resp = null; }
if (xhr.status === 200 && resp && resp.success && resp.action === 'confirm_restore') {
// 注销账号登录 → 二次确认恢复
loginInProgress = false;
submitBtn.disabled = false;
submitBtn.textContent = '登录';
if (confirm(resp.message + '\n\n确认继续登录将中止注销流程。')) {
doConfirmRestore(email, password);
}
@ -75,6 +84,9 @@
window.location.href = '/';
}, 800);
} else {
loginInProgress = false;
submitBtn.disabled = false;
submitBtn.textContent = '登录';
var msg = (resp && resp.message) ? resp.message : '登录失败,请稍后重试';
window.MetaLab.toast(toast, msg, true);
}
@ -84,6 +96,11 @@
}
function doConfirmRestore(email, password) {
if (loginInProgress) return;
loginInProgress = true;
submitBtn.disabled = true;
submitBtn.textContent = '恢复中...';
var xhr = new XMLHttpRequest();
xhr.open('POST', '/api/auth/confirm-restore', true);
xhr.setRequestHeader('Content-Type', 'application/json');
@ -98,6 +115,9 @@
window.location.href = '/';
}, 800);
} else {
loginInProgress = false;
submitBtn.disabled = false;
submitBtn.textContent = '登录';
var msg = (resp && resp.message) ? resp.message : '操作失败,请稍后重试';
window.MetaLab.toast(toast, msg, true);
}