fix(HEL-243): 当前账号可点击返回,避免切换死路
当前账号行原先只显示对号、不可点击,单账号时只能关网页。现改为整行继续使用且不重新签发会话,并带回切换前的业务页。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
e29d5115fa
commit
d2a165ada8
@@ -21,7 +21,7 @@
|
||||
</script>
|
||||
<link rel="stylesheet" href="/shared/tokens.css?v=20260829-hel240">
|
||||
<link rel="stylesheet" href="/shared/base.css?v=20260806-1">
|
||||
<link rel="stylesheet" href="/shared/auth.css?v=20260829-hel240b">
|
||||
<link rel="stylesheet" href="/shared/auth.css?v=20260829-hel243">
|
||||
<link rel="stylesheet" href="/shared/components/controls.css?v=20260820-2">
|
||||
</head>
|
||||
<body class="login-portal">
|
||||
@@ -90,6 +90,6 @@
|
||||
<section class="login-card" id="loginCard" aria-live="polite"></section>
|
||||
</main>
|
||||
<script src="/shared/api.js?v=20260803-2"></script>
|
||||
<script src="/login/page.js?v=20260829-hel240"></script>
|
||||
<script src="/login/page.js?v=20260829-hel243"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+50
-5
@@ -77,9 +77,22 @@
|
||||
return chips.join("");
|
||||
}
|
||||
|
||||
function returnPath() {
|
||||
const raw = new URLSearchParams(global.location.search).get("next") || "";
|
||||
if (!raw) return "/";
|
||||
try {
|
||||
const url = new URL(raw, global.location.origin);
|
||||
if (url.origin !== global.location.origin) return "/";
|
||||
const path = url.pathname || "/";
|
||||
if (path === "/login" || path.startsWith("/login/")) return "/";
|
||||
return `${path}${url.search}${url.hash}` || "/";
|
||||
} catch (_error) {
|
||||
return "/";
|
||||
}
|
||||
}
|
||||
|
||||
function enterApp() {
|
||||
const next = new URLSearchParams(global.location.search).get("next");
|
||||
global.location.replace(next && next.startsWith("/") ? next : "/");
|
||||
global.location.replace(returnPath());
|
||||
}
|
||||
|
||||
function formMarkup(options) {
|
||||
@@ -120,7 +133,7 @@
|
||||
"login-account-row",
|
||||
current ? "is-current" : "",
|
||||
confirming ? "is-confirming" : "",
|
||||
!managing && !current ? "is-switchable" : "",
|
||||
!managing ? "is-switchable" : "",
|
||||
].filter(Boolean).join(" ");
|
||||
if (managing && confirming) {
|
||||
return [
|
||||
@@ -138,11 +151,12 @@
|
||||
const action = managing
|
||||
? `<button class="login-account-remove" type="button" data-confirm-id="${account.user_id}" aria-label="移除 ${escapeHtml(account.username)}"><svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"><path fill="currentColor" d="M6 2h4l.5 1H14v1H2V3h3.5L6 2zm1 4v6H6V6h1zm3 0v6H9V6h1zM3.5 5H13l-.7 8.2A1.5 1.5 0 0 1 10.81 14H5.19a1.5 1.5 0 0 1-1.49-1.8L3.5 5z"></path></svg></button>`
|
||||
: current
|
||||
? '<span class="login-account-check" aria-hidden="true">✓</span>'
|
||||
? '<span class="login-account-action"><span class="login-account-check" aria-hidden="true">✓</span>继续使用</span>'
|
||||
: "";
|
||||
const switchAttr = !managing && !current ? ` data-switch-id="${account.user_id}"` : "";
|
||||
const resumeAttr = !managing && current ? ` data-resume-id="${account.user_id}"` : "";
|
||||
return [
|
||||
`<div class="${classes}" data-user-id="${account.user_id}"${switchAttr}>`,
|
||||
`<div class="${classes}" data-user-id="${account.user_id}"${switchAttr}${resumeAttr}>`,
|
||||
`<span class="login-avatar tone-${tone}" aria-hidden="true">${glyph}</span>`,
|
||||
'<div class="login-account-meta">',
|
||||
'<div class="login-account-name">',
|
||||
@@ -160,6 +174,9 @@
|
||||
const count = state.accounts.length;
|
||||
const managing = state.view === "manage";
|
||||
return [
|
||||
managing
|
||||
? ""
|
||||
: '<button class="login-back" type="button" data-login-action="resume">返回复盘</button>',
|
||||
`<h2 class="login-card-title">${managing ? "管理账号记录" : "选择账号"}</h2>`,
|
||||
`<p class="login-card-lead">${managing
|
||||
? "移除只删除这台电脑上的登录记录,不会注销账号"
|
||||
@@ -210,6 +227,10 @@
|
||||
card.querySelectorAll("[data-login-action]").forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const action = button.dataset.loginAction;
|
||||
if (action === "resume") {
|
||||
resumeCurrentAccount();
|
||||
return;
|
||||
}
|
||||
if (action === "picker") {
|
||||
state.view = state.accounts.length ? "picker" : "first";
|
||||
state.confirmingId = null;
|
||||
@@ -228,6 +249,9 @@
|
||||
card.querySelectorAll("[data-switch-id]").forEach((button) => {
|
||||
button.addEventListener("click", () => switchAccount(Number(button.dataset.switchId)));
|
||||
});
|
||||
card.querySelectorAll("[data-resume-id]").forEach((button) => {
|
||||
button.addEventListener("click", () => resumeCurrentAccount());
|
||||
});
|
||||
card.querySelectorAll("[data-confirm-id]").forEach((button) => {
|
||||
button.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
@@ -291,6 +315,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function resumeCurrentAccount() {
|
||||
state.loading = true;
|
||||
setError("");
|
||||
render();
|
||||
try {
|
||||
const session = await api.request("/api/auth/me");
|
||||
const sessionUserId = session.user?.id;
|
||||
const matches = Boolean(session.authenticated) && (
|
||||
!state.currentUserId || Number(sessionUserId) === Number(state.currentUserId)
|
||||
);
|
||||
if (!matches) {
|
||||
throw new Error("当前会话已失效,请重新登录");
|
||||
}
|
||||
enterApp();
|
||||
} catch (error) {
|
||||
state.loading = false;
|
||||
setError(error.message || "当前会话已失效,请重新登录");
|
||||
render();
|
||||
}
|
||||
}
|
||||
|
||||
async function forgetAccount(userId) {
|
||||
try {
|
||||
await api.request("/api/auth/forget", "POST", { user_id: userId });
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
"/shared/table.js?v=20260803-1",
|
||||
"/shared/theme.js?v=20260803-1",
|
||||
"/shared/dashboard.js?v=20260820-1",
|
||||
"/shared/session.js?v=20260803-1",
|
||||
"/shared/session.js?v=20260829-hel243",
|
||||
"/shared/admin.js?v=20260803-1",
|
||||
"/app.js?v=20260803-2",
|
||||
];
|
||||
|
||||
@@ -2389,6 +2389,18 @@ body.login-portal {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.login-account-action {
|
||||
display: grid;
|
||||
|
||||
justify-items: end;
|
||||
|
||||
gap: 2px;
|
||||
|
||||
color: var(--action);
|
||||
|
||||
font-size: var(--font-size-caption);
|
||||
}
|
||||
|
||||
.login-account-remove {
|
||||
display: grid;
|
||||
|
||||
|
||||
@@ -196,7 +196,13 @@ async function changeAccountPassword(event) {
|
||||
|
||||
async function switchAccount() {
|
||||
toggleAccountDropdown(false);
|
||||
window.location.assign("/login/");
|
||||
const params = new URLSearchParams();
|
||||
const next = `${window.location.pathname}${window.location.search}${window.location.hash}`;
|
||||
if (next.startsWith("/") && !next.startsWith("//") && next !== "/login" && !next.startsWith("/login/") && !next.startsWith("/login?")) {
|
||||
params.set("next", next);
|
||||
}
|
||||
const query = params.toString();
|
||||
window.location.assign("/login/" + (query ? `?${query}` : ""));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user