This commit is contained in:
qsc
2026-09-05 03:05:34 +08:00
parent 524090e769
commit bc4a38f589
7 changed files with 125 additions and 7 deletions
+29
View File
@@ -7,6 +7,7 @@ const state = {
servers: [],
events: {},
session_control: { mode: "all", entries: [] },
token_stats: null,
};
const editing = { bindingSession: null, controlSession: null, aliasServer: null, kungfuPzid: null };
const restoreConfirmationTimers = new WeakMap();
@@ -14,6 +15,33 @@ let toastTimer;
const byId = (id) => document.getElementById(id);
function formatUsageCount(value) {
return Number.isSafeInteger(value) && value >= 0
? value.toLocaleString("zh-CN")
: "—";
}
function renderTokenStats() {
const stats = state.token_stats;
byId("token-level").textContent = Number.isSafeInteger(stats?.level)
? `LV.${stats.level}`
: "—";
byId("token-used").textContent = formatUsageCount(stats?.used);
byId("token-remaining").textContent = formatUsageCount(stats?.remaining);
const status = byId("token-valid");
status.classList.remove("token-status--valid", "token-status--invalid");
if (stats?.valid === true) {
status.textContent = "有效";
status.classList.add("token-status--valid");
} else if (stats?.valid === false) {
status.textContent = "无效";
status.classList.add("token-status--invalid");
} else {
status.textContent = "未获取";
}
}
function showToast(message, isError = false) {
const toast = byId("toast");
toast.textContent = message;
@@ -525,6 +553,7 @@ function renderKungfu() {
}
function render() {
renderTokenStats();
renderServerOptions();
renderSessionOptions();
renderSessionControl();
+19
View File
@@ -17,6 +17,25 @@
<button class="button button--secondary" id="refresh" type="button">刷新数据</button>
</header>
<section class="token-summary" aria-label="JX3API 令牌统计">
<div class="token-stat">
<span>令牌等级</span>
<strong id="token-level"></strong>
</div>
<div class="token-stat">
<span>已用次数</span>
<strong id="token-used"></strong>
</div>
<div class="token-stat">
<span>剩余次数</span>
<strong id="token-remaining"></strong>
</div>
<div class="token-stat">
<span>令牌状态</span>
<strong class="token-status" id="token-valid">未获取</strong>
</div>
</section>
<nav class="tabs" aria-label="管理分类" role="tablist">
<button class="tab is-active" type="button" role="tab" aria-selected="true" data-tab="session-control">会话控制</button>
<button class="tab" type="button" role="tab" aria-selected="false" data-tab="subscriptions">事件推送</button>
+13
View File
@@ -49,6 +49,14 @@ h1 { margin: 0; font-size: clamp(26px, 3vw, 36px); line-height: 1.2; letter-spac
.button--secondary:hover { border-color: color-mix(in srgb, var(--text) 24%, var(--border)); }
.button--danger { color: #fff; background: var(--danger); border-color: var(--danger); }
.button--danger:hover { background: color-mix(in srgb, var(--danger) 88%, #000); border-color: transparent; }
.token-summary { display: grid; grid-template-columns: repeat(4, 1fr); overflow: hidden; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow); }
.token-stat { display: flex; min-height: 104px; flex-direction: column; justify-content: center; padding: 20px 26px; }
.token-stat + .token-stat { border-left: 1px solid var(--border); }
.token-stat span { color: var(--muted); font-size: 13px; font-weight: 700; }
.token-stat strong { margin-top: 3px; font-size: 28px; line-height: 1.3; font-variant-numeric: tabular-nums; }
.token-status { color: var(--muted); }
.token-status--valid { color: var(--success); }
.token-status--invalid { color: var(--danger); }
.tabs { display: flex; gap: 30px; margin-top: 24px; border-bottom: 1px solid var(--border); }
.tab { position: relative; padding: 14px 4px 15px; border: 0; background: transparent; color: var(--muted); cursor: pointer; font-weight: 650; }
.tab:hover, .tab.is-active { color: var(--accent); }
@@ -112,6 +120,11 @@ tbody tr.is-editing { background: color-mix(in srgb, var(--accent-soft) 62%, tra
.shell { width: min(100% - 24px, 1260px); padding-top: 20px; }
.page-header { align-items: stretch; flex-direction: column; }
.section-intro--actions { align-items: stretch; flex-direction: column; }
.token-summary { grid-template-columns: repeat(2, 1fr); }
.token-stat { min-height: 88px; padding: 15px 18px; }
.token-stat:nth-child(3) { border-top: 1px solid var(--border); border-left: 0; }
.token-stat:nth-child(4) { border-top: 1px solid var(--border); }
.token-stat strong { font-size: 24px; }
.tabs { gap: 16px; overflow-x: auto; }
.tab { flex: 0 0 auto; }
.editor { grid-template-columns: 1fr; }