feat: MCP Token 复制按钮 — 后台一键取回明文 Token 到剪贴板

This commit is contained in:
2026-09-11 15:10:57 +08:00
parent 861f132274
commit 8cf91aed9a
3 changed files with 43 additions and 0 deletions
+32
View File
@@ -139,6 +139,7 @@
<label style="font-size:12px; color:#666">Token</label>
<div style="display:flex; gap:8px; align-items:center">
<input type="text" id="cfg_mcp_token" class="input" readonly style="flex:1; background:#fff; color:#555">
<button class="btn btn-primary" onclick="copyMCPToken(this)" style="padding:8px 14px; white-space:nowrap">📋 复制</button>
<button class="btn btn-primary" onclick="regenMCPToken()" style="padding:8px 14px; white-space:nowrap">🔄 重新生成</button>
</div>
<div style="font-size:11px; color:#999; margin-top:6px">
@@ -200,6 +201,37 @@
});
}
async function copyMCPToken(btn) {
try {
const resp = await fetch('/admin/api/mcp/token');
const res = await resp.json();
if (!res.success) { alert('❌ ' + (res.message || 'Token 未生成')); return; }
const token = res.token;
let copied = false;
try {
await navigator.clipboard.writeText(token);
copied = true;
} catch (e) {
// 非 HTTPS/localhost 环境降级方案
const ta = document.createElement('textarea');
ta.value = token;
ta.style.position = 'fixed';
ta.style.opacity = '0';
document.body.appendChild(ta);
ta.focus(); ta.select();
try { copied = document.execCommand('copy'); } catch (e2) {}
document.body.removeChild(ta);
}
if (copied) {
const old = btn.textContent;
btn.textContent = '✅ 已复制';
setTimeout(() => { btn.textContent = old; }, 1500);
} else {
prompt('自动复制不可用,请手动复制 Token:', token);
}
} catch(e) { alert('获取 Token 失败'); }
}
async function regenMCPToken() {
if (!confirm('确定重新生成 Token?\n\n旧 Token 将立即失效,已接入的 AI 客户端需要更新为新 Token。')) return;
try {