fix: compact token auth ui
This commit is contained in:
@@ -414,6 +414,46 @@ function renderPage() {
|
||||
color: var(--ink);
|
||||
}
|
||||
textarea { min-height: 88px; resize: vertical; }
|
||||
.field-note {
|
||||
font-size: 12px;
|
||||
color: rgba(74, 96, 107, 0.9);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.advanced-box {
|
||||
border: 1px solid rgba(22, 49, 61, 0.12);
|
||||
border-radius: 16px;
|
||||
background: rgba(255, 255, 255, 0.66);
|
||||
padding: 0 14px;
|
||||
}
|
||||
.advanced-box[open] {
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
.advanced-toggle {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
color: var(--ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
.advanced-toggle::-webkit-details-marker { display: none; }
|
||||
.advanced-toggle::after {
|
||||
content: "展开";
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--muted);
|
||||
}
|
||||
.advanced-box[open] .advanced-toggle::after {
|
||||
content: "收起";
|
||||
}
|
||||
.token-summary {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--muted);
|
||||
}
|
||||
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
|
||||
.checks {
|
||||
display: grid;
|
||||
@@ -786,15 +826,27 @@ function renderPage() {
|
||||
</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>
|
||||
已有 Token(可选)
|
||||
<input id="token" name="token" placeholder="Bearer token,可替代账号密码" />
|
||||
</label>
|
||||
<label>
|
||||
最大作品页抓取数
|
||||
<input id="max-videos" name="maxVideos" type="number" min="0" max="10" value="4" />
|
||||
</label>
|
||||
<div class="field-note" style="display:flex;align-items:end;">
|
||||
已登录工作台后会自动复用当前会话 Token。通常只需要填账号密码,不需要手动维护 Token。
|
||||
</div>
|
||||
</div>
|
||||
<details class="advanced-box" id="token-details">
|
||||
<summary class="advanced-toggle">
|
||||
<span>高级认证</span>
|
||||
<span class="token-summary" id="token-summary">未填写 Token</span>
|
||||
</summary>
|
||||
<div class="stack">
|
||||
<label>
|
||||
已有 Token(可选)
|
||||
<input id="token" name="token" placeholder="Bearer token,可替代账号密码" autocomplete="off" />
|
||||
</label>
|
||||
<div class="field-note">只有在你已经拿到 Bearer Token,或者不希望页面保存密码时,再手动填写这里。</div>
|
||||
</div>
|
||||
</details>
|
||||
<div class="checks">
|
||||
<label class="check"><input id="sync-enabled" type="checkbox" checked /> 导入 StoryForge</label>
|
||||
<label class="check"><input id="headless" type="checkbox" /> Headless</label>
|
||||
@@ -1001,6 +1053,9 @@ function renderPage() {
|
||||
const storageKey = "storyforge-douyin-control-panel";
|
||||
const sessionStorageKey = "storyforge-douyin-workbench-session";
|
||||
const workbenchSessionEl = document.getElementById("workbench-session");
|
||||
const tokenDetailsEl = document.getElementById("token-details");
|
||||
const tokenInputEl = document.getElementById("token");
|
||||
const tokenSummaryEl = document.getElementById("token-summary");
|
||||
const accountsCountPillEl = document.getElementById("accounts-count-pill");
|
||||
const accountsListEl = document.getElementById("accounts-list");
|
||||
const accountsFilterEl = document.getElementById("accounts-filter");
|
||||
@@ -1110,7 +1165,7 @@ function renderPage() {
|
||||
const backendUrl = normalizeBackendUrl(document.getElementById("backend-url").value);
|
||||
const username = document.getElementById("username").value.trim();
|
||||
const password = document.getElementById("password").value;
|
||||
const token = document.getElementById("token").value.trim();
|
||||
const token = tokenInputEl.value.trim();
|
||||
return {
|
||||
backendUrl,
|
||||
username,
|
||||
@@ -1119,6 +1174,14 @@ function renderPage() {
|
||||
};
|
||||
}
|
||||
|
||||
function updateTokenUi() {
|
||||
const token = tokenInputEl.value.trim();
|
||||
tokenSummaryEl.textContent = token ? "已填写 Token" : "未填写 Token";
|
||||
if (!token && document.activeElement !== tokenInputEl) {
|
||||
tokenDetailsEl.open = false;
|
||||
}
|
||||
}
|
||||
|
||||
function persistWorkbenchSession(session) {
|
||||
workbenchState.session = session;
|
||||
localStorage.setItem(sessionStorageKey, JSON.stringify(session));
|
||||
@@ -1352,7 +1415,7 @@ function renderPage() {
|
||||
'<div class="status-line"><strong>当前账号</strong><span>' + escapeHtml(session.account?.display_name || session.account?.username || "未知账号") + '</span></div>',
|
||||
'<div class="status-line"><strong>角色</strong><span>' + escapeHtml(session.account?.role || "-") + '</span></div>',
|
||||
'<div class="status-line"><strong>后端地址</strong><span class="path">' + escapeHtml(session.backendUrl) + '</span></div>',
|
||||
'<div class="status-line"><strong>Token</strong><span class="mono">' + escapeHtml((session.token || "").slice(0, 12)) + "..." + '</span></div>'
|
||||
'<div class="status-line"><strong>认证状态</strong><span>Token 已缓存,可直接刷新工作台或复用到采集任务</span></div>'
|
||||
].join("");
|
||||
}
|
||||
|
||||
@@ -1747,7 +1810,7 @@ function renderPage() {
|
||||
if (saved.profileUrl) document.getElementById("profile-url").value = saved.profileUrl;
|
||||
if (saved.backendUrl) document.getElementById("backend-url").value = saved.backendUrl;
|
||||
if (saved.username) document.getElementById("username").value = saved.username;
|
||||
if (saved.token) document.getElementById("token").value = saved.token;
|
||||
if (saved.token) tokenInputEl.value = saved.token;
|
||||
if (saved.note) document.getElementById("note").value = saved.note;
|
||||
if (saved.maxVideos !== undefined) document.getElementById("max-videos").value = saved.maxVideos;
|
||||
if (saved.syncEnabled !== undefined) document.getElementById("sync-enabled").checked = Boolean(saved.syncEnabled);
|
||||
@@ -1755,6 +1818,7 @@ function renderPage() {
|
||||
if (saved.skipCreatorCenter !== undefined) document.getElementById("skip-creator-center").checked = Boolean(saved.skipCreatorCenter);
|
||||
if (saved.allowCreatorCenterFallback !== undefined) document.getElementById("allow-fallback").checked = Boolean(saved.allowCreatorCenterFallback);
|
||||
} catch {}
|
||||
updateTokenUi();
|
||||
}
|
||||
|
||||
function saveValues(payload) {
|
||||
@@ -1782,8 +1846,8 @@ function renderPage() {
|
||||
password: document.getElementById("password").value,
|
||||
storyforgeUsername: document.getElementById("username").value.trim(),
|
||||
storyforgePassword: document.getElementById("password").value,
|
||||
token: document.getElementById("token").value.trim(),
|
||||
storyforgeToken: document.getElementById("token").value.trim(),
|
||||
token: tokenInputEl.value.trim(),
|
||||
storyforgeToken: tokenInputEl.value.trim(),
|
||||
note: document.getElementById("note").value.trim(),
|
||||
maxVideos: document.getElementById("max-videos").value,
|
||||
syncEnabled: document.getElementById("sync-enabled").checked,
|
||||
@@ -1813,6 +1877,18 @@ function renderPage() {
|
||||
await refreshStatus();
|
||||
});
|
||||
|
||||
tokenInputEl.addEventListener("focus", () => {
|
||||
tokenDetailsEl.open = true;
|
||||
});
|
||||
tokenInputEl.addEventListener("input", updateTokenUi);
|
||||
tokenDetailsEl.addEventListener("toggle", () => {
|
||||
if (tokenDetailsEl.open) {
|
||||
tokenSummaryEl.textContent = tokenInputEl.value.trim() ? "已填写 Token" : "填写后可跳过密码";
|
||||
} else {
|
||||
updateTokenUi();
|
||||
}
|
||||
});
|
||||
|
||||
workbenchLoginButton.addEventListener("click", loginWorkbench);
|
||||
|
||||
workbenchRefreshButton.addEventListener("click", async () => {
|
||||
|
||||
Reference in New Issue
Block a user