From f254a7bcfa0cf025fcabd9910dbc53276f5a9a0f Mon Sep 17 00:00:00 2001 From: argszero Date: Sat, 22 Aug 2026 09:02:54 +0800 Subject: [PATCH] fix(ui): tx table token K/M abbreviation + hover exact + summary right-align + key/type label fallback (rant 2026-08-22T08:58:54) --- ui/css/style.css | 2 +- ui/index.html | 10 +++++----- ui/js/app.js | 33 +++++++++++++++++++++++++-------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/ui/css/style.css b/ui/css/style.css index 8ffa166..d1cca21 100644 --- a/ui/css/style.css +++ b/ui/css/style.css @@ -320,7 +320,7 @@ select.input option { background: var(--bg-card); } /* 交易汇总条(rant 20:39:30 B:紧凑 inline 条,随 tab/筛选联动) */ .tx-summary { display: flex; flex-wrap: wrap; gap: 28px; padding: 12px 16px 10px; border-bottom: 1px solid var(--border); } -.tx-summary .ts-item { display: flex; flex-direction: column; gap: 2px; } +.tx-summary .ts-item { display: flex; flex-direction: column; gap: 2px; align-items: flex-end; } .tx-summary .ts-label { color: var(--text-mute); font-size: 12px; } .tx-summary .ts-value { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; } .tx-summary .ts-value.ok { color: var(--ok); } diff --git a/ui/index.html b/ui/index.html index db045f8..66aefd0 100644 --- a/ui/index.html +++ b/ui/index.html @@ -5,7 +5,7 @@ AITokenPool - + @@ -673,9 +673,9 @@

使用模型

- - - - + + + + diff --git a/ui/js/app.js b/ui/js/app.js index f5c261a..d0bf53b 100644 --- a/ui/js/app.js +++ b/ui/js/app.js @@ -1174,13 +1174,13 @@ { key: "model", title: () => T("tx.col.model"), sort: "string", filter: "text" }, { key: "key", title: () => T("tx.col.key"), sort: "string", filter: "text" }, { key: "input", title: () => T("tx.col.input"), sort: "number", filter: "number-range", align: "num", - render: (t) => t.inputTokens }, + render: (t) => '' + t.inputTokens + "" }, { key: "cached", title: () => T("tx.col.cached"), sort: "number", filter: "number-range", align: "num", - render: (t) => t.cachedTokens }, + render: (t) => '' + t.cachedTokens + "" }, { key: "output", title: () => T("tx.col.output"), sort: "number", filter: "number-range", align: "num", - render: (t) => t.outputTokens }, + render: (t) => '' + t.outputTokens + "" }, { key: "tokens", title: () => T("tx.col.tokens"), sort: "number", filter: "number-range", align: "num", - render: (t) => t.tokens }, + render: (t) => '' + t.tokens + "" }, { key: "pts", title: () => T("tx.col.pts"), sort: "number", filter: "number-range", align: "num", render: (t) => '' + (t.pts > 0 ? "+" : "") + D.fmt(t.pts) + "" }, { key: "status", title: () => T("tx.col.status"), sort: "string", filter: "select", @@ -2472,21 +2472,33 @@ } // 后端 transactions items → 视图行(模型 / Key 两列 + Token 四列平铺;rant 2026-08-22T06:36:54/06:37:50/06:39:04) - const fmtTokens = (n) => (typeof n === "number" && n > 0 ? (n >= 1e6 ? (n / 1e6).toFixed(2) + "M" : String(Math.round(n))) : "0"); + // rant 2026-08-22T08:58:54:Token 数字加 K/M 缩写,悬停显示精确值 + const fmtTokens = (n) => { + if (typeof n !== "number" || !(n > 0)) return "0"; + if (n >= 1e6) return (n / 1e6).toFixed(2) + "M"; + if (n >= 1000) return (n / 1000).toFixed(1).replace(/\.0$/, "") + "K"; + return String(Math.round(n)); + }; + const fmtTokensExact = (n) => (typeof n === "number" ? String(Math.round(n)) : "0"); function txsToView(items) { return items.map((t) => { let tokens = "—"; if (typeof t.tokens === "number" && t.tokens > 0) { - tokens = t.tokens >= 1e6 ? (t.tokens / 1e6).toFixed(2) + "M" : String(Math.round(t.tokens)); + tokens = fmtTokens(t.tokens); } // Token 四列:输入(非缓存) / 缓存 / 输出 / 总;旧记录(cached/output=0)输入=总 const inputTokens = fmtTokens(typeof t.input_tokens === "number" ? t.input_tokens : null); const cachedTokens = fmtTokens(typeof t.cached_tokens === "number" ? t.cached_tokens : null); const outputTokens = fmtTokens(typeof t.output_tokens === "number" ? t.output_tokens : null); + // 悬停显示精确值(K/M 缩写下的全量) + const brkTitle = (label, v) => { + const exact = typeof v === "number" && v > 0 ? fmtTokensExact(v) : "0"; + return ' title="' + esc(label + ": " + exact) + '"'; + }; // 模型列:consume/earn 显示模型名;无模型(topup/gift 等)显示交易类型说明 - // Key 列:key_label(note / provider / provider / plan);无 key → — + // Key 列:key_label(note / provider / provider / plan);无 key 的有类型交易(topup/gift/withdraw)显示交易类型说明,consume/earn 无 key 显示 — const model = t.model || txType(t.type); - const key = t.key_label || "—"; + const key = t.key_label || (t.type === "consume" || t.type === "earn" ? "—" : txType(t.type)); return { id: t.id, time: (t.time || "").replace("T", " ").slice(0, 16), @@ -2495,9 +2507,14 @@ key, detail: t.model ? "消费 · " + t.model : "交易", tokens, + tokensRaw: typeof t.tokens === "number" ? t.tokens : null, inputTokens, + inputRaw: typeof t.input_tokens === "number" ? t.input_tokens : null, cachedTokens, + cachedRaw: typeof t.cached_tokens === "number" ? t.cached_tokens : null, outputTokens, + outputRaw: typeof t.output_tokens === "number" ? t.output_tokens : null, + tokenBrk: brkTitle, pts: t.pts, status: t.status || "成功", };