dsh-account-pool 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/lib/client.js +44 -88
- package/lib/index.js +15 -24
- package/lib/trae-upstream.js +5 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,6 +117,14 @@ dsh plugin --profile web add dsh-account-pool
|
|
|
117
117
|
|
|
118
118
|
全完成显示绿色 `3/3 已完成`,部分完成显示黄色 `2/3`,没做显示灰色 `0/3`。
|
|
119
119
|
|
|
120
|
+
清单底部还有一行**今日获得积分**:点「全部执行」后,用**执行前后的余额差**
|
|
121
|
+
算出这次实际到手的积分。
|
|
122
|
+
|
|
123
|
+
为什么用差值:签到接口只回成功/失败、不回奖励数量,Trae 的任务流也没有
|
|
124
|
+
计费字段——余额差是唯一可靠的真值。只把**正差值**算作获得(负差值可能是
|
|
125
|
+
期间用了额度);算不出时显示 `—` 而不是编造数字;部分账号缺数据时会注明
|
|
126
|
+
「合计可能偏低」。
|
|
127
|
+
|
|
120
128
|
### 只读与执行分离
|
|
121
129
|
|
|
122
130
|
**打开页面只做只读查询,不会替你签到或派出。** 点「全部执行」才真正执行。
|
|
@@ -176,10 +184,15 @@ dsh plugin --profile web add dsh-account-pool
|
|
|
176
184
|
|---|---|
|
|
177
185
|
| 请求数 / 失败数 | **失败的尝试也计入请求数**,这样「重试放大」才看得出来 |
|
|
178
186
|
| 输入 / 输出 / 总 tokens | 取自上游 SSE 末尾的 `usage` 帧 |
|
|
179
|
-
| 积分消耗 | 上游 `usage.credit
|
|
187
|
+
| 积分消耗 | 上游 `usage.credit`。**只有逐次上报消耗的上游才有这一格**(WorkBuddy);Trae 的对话流没有计费字段,该指标整块隐藏,而不是显示恒为 0 |
|
|
180
188
|
| 平均延迟 | 按样本数加权,不是对每桶均值再取平均 |
|
|
181
189
|
| 按模型明细 | 每个模型的请求、失败、token、积分 |
|
|
182
190
|
|
|
191
|
+
> Trae 为什么没有积分消耗:它的对话流只有 6 种事件
|
|
192
|
+
> (`metadata` / `timing_cost` / `output` / `extra_info` / `token_usage` / `done`),
|
|
193
|
+
> 没有任何计费字段。积分接口虽然能给「账号累计已消耗」,但那是账号总量、
|
|
194
|
+
> 不是本页消耗,混着展示会误导,所以不提供。
|
|
195
|
+
|
|
183
196
|
保留策略:按小时分桶;当桶数超过上限(20 万)时,把**超过 90 天**的小时桶
|
|
184
197
|
折叠为日桶(日桶长期保留)。折叠由**桶数上限触发**,不是按时间定时执行——
|
|
185
198
|
所以在流量不大的情况下,历史小时桶会原样保留,不会自动精简。
|
package/lib/client.js
CHANGED
|
@@ -453,26 +453,6 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
453
453
|
h("td", { style: Object.assign({}, TD_STYLE, { fontSize: "12px", opacity: 0.7 }) }, note || ""),
|
|
454
454
|
);
|
|
455
455
|
|
|
456
|
-
/**
|
|
457
|
-
* 「今日获得积分」统计行。
|
|
458
|
-
*
|
|
459
|
-
* 数据来源是执行前后两次余额的差值(签到接口不回奖励数量,
|
|
460
|
-
* Trae 的任务流也没有计费字段)。所以:
|
|
461
|
-
* - 没执行过 → 显示「未执行」,不猜
|
|
462
|
-
* - 执行过但算式缺数据 → 显示「—」
|
|
463
|
-
* - 有数字 → 显示合计,部分账号缺数据时加注
|
|
464
|
-
*/
|
|
465
|
-
const earnedRow = () => h("tr", { key: "earned" },
|
|
466
|
-
h("td", { style: Object.assign({}, TD_STYLE, { fontWeight: 600 }) }, "今日获得积分"),
|
|
467
|
-
h("td", { style: Object.assign({}, TD_STYLE, NUM_STYLE, { color: "var(--dsw-alias-state-success-primary)" }) },
|
|
468
|
-
typeof lastRun?.totalEarned === "number"
|
|
469
|
-
? "+" + formatNumber(lastRun.totalEarned)
|
|
470
|
-
: h("span", { style: { opacity: 0.5 } }, lastRun ? "—" : "未执行")),
|
|
471
|
-
h("td", { style: Object.assign({}, TD_STYLE, { fontSize: "12px", opacity: 0.7 }) },
|
|
472
|
-
typeof lastRun?.totalEarned === "number"
|
|
473
|
-
? (lastRun.earnedPartial ? "部分账号余额未取到,合计可能偏低" : "执行前后余额之差")
|
|
474
|
-
: "点「全部执行」后统计"),
|
|
475
|
-
);
|
|
476
456
|
|
|
477
457
|
return h("div", null,
|
|
478
458
|
h("div", { style: CARD_STYLE },
|
|
@@ -501,7 +481,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
501
481
|
const map = {};
|
|
502
482
|
for (const r of out.results || []) map[r.accountId] = r;
|
|
503
483
|
// 把「本次获得的总积分」也带进 lastRun,供统计行显示
|
|
504
|
-
onRunDone(map
|
|
484
|
+
onRunDone(map);
|
|
505
485
|
// 提示里带上实际到手的积分,比干巴巴一句"已完成"有用
|
|
506
486
|
setNotice(region, "ok", grantedText(out.totalEarned, "每日任务"));
|
|
507
487
|
// 重新拉只读状态,让旅行/抽奖/连登的完成数同步更新
|
|
@@ -535,7 +515,6 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
535
515
|
taskRow("猫猫旅行", travelDone, "到站领奖 · 空闲派出", "今日已派或在途都算完成"),
|
|
536
516
|
taskRow("连登兑换", redeemDone, "满 7/14/28 天可兑换", redeemPending > 0 ? redeemPending + " 个账号有可兑换档位" : "没有待兑换的档位"),
|
|
537
517
|
taskRow("抽奖", lotteryDone, "次数来自连登兑换", lotteryPending > 0 ? lotteryPending + " 个账号有抽奖次数" : "暂无抽奖次数"),
|
|
538
|
-
earnedRow(),
|
|
539
518
|
),
|
|
540
519
|
),
|
|
541
520
|
|
|
@@ -555,6 +534,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
555
534
|
h("th", { style: TH_STYLE }, "猫"),
|
|
556
535
|
h("th", { style: TH_STYLE }, "旅行"),
|
|
557
536
|
h("th", { style: TH_STYLE }, "抽奖次数"),
|
|
537
|
+
h("th", { style: TH_STYLE }, "今日获得"),
|
|
558
538
|
)),
|
|
559
539
|
h("tbody", null, accounts.map(a => h("tr", { key: a.accountId },
|
|
560
540
|
h("td", { style: TD_STYLE }, a.nickname || a.accountId?.slice(0, 8) || "—"),
|
|
@@ -580,6 +560,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
580
560
|
: h("span", { style: { opacity: 0.5 } }, "—")),
|
|
581
561
|
h("td", { style: TD_STYLE },
|
|
582
562
|
a.lottery !== undefined ? String(a.lottery.chances) : h("span", { style: { opacity: 0.5 } }, "—")),
|
|
563
|
+
h("td", { style: TD_STYLE }, earnedCell(a, lastRun)),
|
|
583
564
|
))),
|
|
584
565
|
),
|
|
585
566
|
),
|
|
@@ -633,6 +614,27 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
633
614
|
return what + "完成,获得 " + formatNumber(totalEarned) + " 积分";
|
|
634
615
|
}
|
|
635
616
|
|
|
617
|
+
/**
|
|
618
|
+
* 账号明细里的「今日获得」单元格。
|
|
619
|
+
*
|
|
620
|
+
* 数值来自本次执行的**余额前后差**(后端在 tasks/daily 里算好,
|
|
621
|
+
* 挂在每账号结果的 earnedCredits 上)。
|
|
622
|
+
*
|
|
623
|
+
* 三态刻意区分开:
|
|
624
|
+
* 没执行过 → 未执行(灰)
|
|
625
|
+
* 算出来了 → +N(绿);0 也显示 +0,因为「确实没加」与「不知道」不同
|
|
626
|
+
* 算不出 → —(灰),不编造
|
|
627
|
+
*/
|
|
628
|
+
function earnedCell(account, lastRun) {
|
|
629
|
+
const run = lastRun?.[account.accountId];
|
|
630
|
+
if (!run) return h("span", { style: { opacity: 0.5 } }, "未执行");
|
|
631
|
+
const earned = run.earnedCredits;
|
|
632
|
+
if (typeof earned !== "number") return h("span", { style: { opacity: 0.5 } }, "—");
|
|
633
|
+
return h("span", {
|
|
634
|
+
style: { color: earned > 0 ? "var(--dsw-alias-state-success-primary)" : "inherit" },
|
|
635
|
+
}, "+" + formatNumber(earned));
|
|
636
|
+
}
|
|
637
|
+
|
|
636
638
|
function checkinCell(account) {
|
|
637
639
|
if (account.checkinError) {
|
|
638
640
|
return h("span", { style: { color: "var(--dsw-alias-state-error-primary)", fontSize: "12px" } }, "查询失败");
|
|
@@ -665,23 +667,6 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
665
667
|
|
|
666
668
|
const sumCredits = accounts.reduce((sum, a) => sum + (typeof a.credits === "number" ? a.credits : 0), 0);
|
|
667
669
|
|
|
668
|
-
/**
|
|
669
|
-
* 「今日获得积分」统计行。
|
|
670
|
-
*
|
|
671
|
-
* 与 WorkBuddy 同源:执行前后两次余额的差值。Trae 的签到接口
|
|
672
|
-
* 只回成功/失败,任务流也没有计费字段,差值是真值。
|
|
673
|
-
*/
|
|
674
|
-
const earnedRow = () => h("tr", { key: "earned" },
|
|
675
|
-
h("td", { style: Object.assign({}, TD_STYLE, { fontWeight: 600 }) }, "今日获得积分"),
|
|
676
|
-
h("td", { style: Object.assign({}, TD_STYLE, NUM_STYLE, { color: "var(--dsw-alias-state-success-primary)" }) },
|
|
677
|
-
typeof lastRun?.totalEarned === "number"
|
|
678
|
-
? "+" + formatNumber(lastRun.totalEarned)
|
|
679
|
-
: h("span", { style: { opacity: 0.5 } }, lastRun ? "—" : "未执行")),
|
|
680
|
-
h("td", { style: Object.assign({}, TD_STYLE, { fontSize: "12px", opacity: 0.7 }) },
|
|
681
|
-
typeof lastRun?.totalEarned === "number"
|
|
682
|
-
? (lastRun.earnedPartial ? "部分账号余额未取到,合计可能偏低" : "执行前后余额之差")
|
|
683
|
-
: "点「全部执行」后统计"),
|
|
684
|
-
);
|
|
685
670
|
|
|
686
671
|
const taskRow = (name, done, note) => h("tr", { key: name },
|
|
687
672
|
h("td", { style: TD_STYLE }, name),
|
|
@@ -715,7 +700,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
715
700
|
if (!out.ok) throw new Error(out.error || "执行失败");
|
|
716
701
|
const map = {};
|
|
717
702
|
for (const r of out.results || []) map[r.accountId] = r;
|
|
718
|
-
onRunDone(map
|
|
703
|
+
onRunDone(map);
|
|
719
704
|
setNotice(region, "ok", grantedText(out.totalEarned, "签到"));
|
|
720
705
|
await reload();
|
|
721
706
|
} catch (error) {
|
|
@@ -745,7 +730,6 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
745
730
|
h("tbody", null,
|
|
746
731
|
taskRow("每日签到", checkedIn, "每天一次,先查状态再领取,不会重复领"),
|
|
747
732
|
taskRow("积分查询", withCredits, total > 0 ? "当前合计 " + formatNumber(sumCredits) + " 积分" : "只读查询,不消耗额度"),
|
|
748
|
-
earnedRow(),
|
|
749
733
|
),
|
|
750
734
|
),
|
|
751
735
|
),
|
|
@@ -759,6 +743,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
759
743
|
h("th", { style: TH_STYLE }, "账号"),
|
|
760
744
|
h("th", { style: TH_STYLE }, "今日签到"),
|
|
761
745
|
h("th", { style: TH_STYLE }, "积分"),
|
|
746
|
+
h("th", { style: TH_STYLE }, "今日获得"),
|
|
762
747
|
)),
|
|
763
748
|
h("tbody", null, accounts.map(a => h("tr", { key: a.accountId },
|
|
764
749
|
h("td", { style: TD_STYLE }, a.nickname || String(a.accountId).slice(0, 8)),
|
|
@@ -767,6 +752,7 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
767
752
|
a.creditsError
|
|
768
753
|
? "—"
|
|
769
754
|
: typeof a.credits === "number" ? formatNumber(a.credits) : "—"),
|
|
755
|
+
h("td", { style: TD_STYLE }, earnedCell(a, lastRun)),
|
|
770
756
|
))),
|
|
771
757
|
),
|
|
772
758
|
)
|
|
@@ -953,30 +939,11 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
953
939
|
const t = usage.totals || {};
|
|
954
940
|
const models = usage.byModel || [];
|
|
955
941
|
const totalCalls = t.requests || 0;
|
|
942
|
+
// 上游是否逐次上报积分消耗。默认按「支持」走,避免老数据缺字段时
|
|
943
|
+
// 把指标整块藏掉;只有后端明确说 false 才隐藏。
|
|
944
|
+
const reportsCredits = usage.reportsPerRequestCredits !== false;
|
|
956
945
|
const failRate = totalCalls > 0 ? (t.errors || 0) / totalCalls : 0;
|
|
957
946
|
|
|
958
|
-
/**
|
|
959
|
-
* 积分消耗指标。
|
|
960
|
-
*
|
|
961
|
-
* 优先用「按请求累加」的值;它为 0 而上游给了累计消耗时,改用
|
|
962
|
-
* 累计值并注明口径不同——这两个数字含义不一样,不能混着看:
|
|
963
|
-
* 按请求累加:本页时间窗口内消耗了多少
|
|
964
|
-
* 累计已消耗:账号从开通到现在的总量(不受时间窗口影响)
|
|
965
|
-
*/
|
|
966
|
-
const creditsKpi = (totals, whole) => {
|
|
967
|
-
const perRequest = typeof totals.credits === "number" ? totals.credits : 0;
|
|
968
|
-
const upstream = whole.upstreamConsumed;
|
|
969
|
-
if (perRequest > 0) {
|
|
970
|
-
return kpi("积分消耗", formatNumber(perRequest), { full: formatNumber(perRequest) + " 积分" });
|
|
971
|
-
}
|
|
972
|
-
if (typeof upstream === "number" && upstream > 0) {
|
|
973
|
-
return kpi("累计消耗", formatNumber(upstream), {
|
|
974
|
-
full: "上游未上报单次消耗,这里显示账号累计已消耗 " + formatNumber(upstream) + " 积分",
|
|
975
|
-
});
|
|
976
|
-
}
|
|
977
|
-
return kpi("积分消耗", formatNumber(perRequest), { full: formatNumber(perRequest) + " 积分" });
|
|
978
|
-
};
|
|
979
|
-
|
|
980
947
|
/** 核心指标块:大号数字 + 小标签。 */
|
|
981
948
|
const kpi = (label, value, opts = {}) => h("div", {
|
|
982
949
|
style: {
|
|
@@ -1073,7 +1040,8 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
1073
1040
|
// 用 grid 而不是 flex-wrap:wrap 在窄面板里会把第 4 块挤到下一行,
|
|
1074
1041
|
// grid 的 1fr 会按可用宽度均分,永远保持一行。
|
|
1075
1042
|
h("div", {
|
|
1076
|
-
|
|
1043
|
+
// 少一个指标时用 3 列网格,避免留下一个空位
|
|
1044
|
+
className: reportsCredits ? "wb-kpi-grid-4" : "wb-kpi-grid-3",
|
|
1077
1045
|
style: {
|
|
1078
1046
|
display: "grid",
|
|
1079
1047
|
gridTemplateColumns: "repeat(4, minmax(0, 1fr))",
|
|
@@ -1091,12 +1059,14 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
1091
1059
|
// 积分精确到个位、不缩写:它是能对账的数字,
|
|
1092
1060
|
// 显示成 8.4K 会让人不知道到底扣了多少。
|
|
1093
1061
|
//
|
|
1094
|
-
//
|
|
1095
|
-
//
|
|
1096
|
-
//
|
|
1097
|
-
//
|
|
1098
|
-
//
|
|
1099
|
-
|
|
1062
|
+
// 上游不逐次上报消耗时整块隐藏(Trae 的对话流没有计费
|
|
1063
|
+
// 字段,累加恒为 0)。显示一个恒为 0 的指标比不显示更糟:
|
|
1064
|
+
// 用户会以为「没消耗」或「统计坏了」,而真相是上游不给。
|
|
1065
|
+
// 也不拿积分接口的累计值来凑数——那是账号总量,不是本页
|
|
1066
|
+
// 消耗,混着展示会直接误导。
|
|
1067
|
+
reportsCredits
|
|
1068
|
+
? kpi("积分消耗", formatNumber(t.credits), { full: formatNumber(t.credits) + " 积分" })
|
|
1069
|
+
: null,
|
|
1100
1070
|
// 延迟只统计成功请求。没有成功请求时显示 —,
|
|
1101
1071
|
// 而不是误导性的 0(或把失败请求的快速返回当成"很快")。
|
|
1102
1072
|
h("div", {
|
|
@@ -1766,24 +1736,10 @@ window.__ModuleLoader__.load({ id: "dsh-account-pool", factory: (require) => {
|
|
|
1766
1736
|
const timer = setInterval(() => setTick(t => t + 1), 1000);
|
|
1767
1737
|
return () => clearInterval(timer);
|
|
1768
1738
|
}, []);
|
|
1769
|
-
//
|
|
1770
|
-
//
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
const [lastRun, setLastRunState] = useState(null);
|
|
1774
|
-
/**
|
|
1775
|
-
* 保存执行结果。
|
|
1776
|
-
*
|
|
1777
|
-
* 按 accountId 建立索引,同时把汇总字段挂在同一个对象上——
|
|
1778
|
-
* 这样「按账号取结果」和「读合计」共用一份状态,不用两个 state
|
|
1779
|
-
* 引起额外的重渲染。
|
|
1780
|
-
*/
|
|
1781
|
-
const setLastRun = useCallback((results, summary) => {
|
|
1782
|
-
setLastRunState(Object.assign({}, results, {
|
|
1783
|
-
totalEarned: summary?.totalEarned,
|
|
1784
|
-
earnedPartial: summary?.earnedPartial === true,
|
|
1785
|
-
}));
|
|
1786
|
-
}, []);
|
|
1739
|
+
// 上次每日任务的执行结果,按 accountId 索引。
|
|
1740
|
+
// 清单里的「完成数」和明细里的「今日获得」都从它取
|
|
1741
|
+
//(签到没有只读接口,这些只能靠执行结果)。
|
|
1742
|
+
const [lastRun, setLastRun] = useState(null);
|
|
1787
1743
|
const pollTimer = useRef(null);
|
|
1788
1744
|
|
|
1789
1745
|
/** 给某个区域设一条提示信息。 */
|
package/lib/index.js
CHANGED
|
@@ -355,6 +355,16 @@ async function createRegionStack({ region, dshHome, config, logger, ctx }) {
|
|
|
355
355
|
region,
|
|
356
356
|
providerId,
|
|
357
357
|
isTrae,
|
|
358
|
+
/**
|
|
359
|
+
* 上游是否**逐次上报**积分消耗。
|
|
360
|
+
*
|
|
361
|
+
* WorkBuddy 的响应里带 credit 字段,能按请求累加;
|
|
362
|
+
* Trae 的对话流只有六种事件(metadata/timing_cost/output/
|
|
363
|
+
* extra_info/token_usage/done),没有任何计费字段——它只在
|
|
364
|
+
* 积分接口给一个累计值。那个累计值不能当「本页消耗」展示
|
|
365
|
+
* (含义不同,会误导),所以这种情况下界面直接不显示该指标。
|
|
366
|
+
*/
|
|
367
|
+
reportsPerRequestCredits: !isTrae,
|
|
358
368
|
runTasks,
|
|
359
369
|
// 只读状态:Trae 用 readStatus,WorkBuddy 用现有的那组查询
|
|
360
370
|
readStatus: isTrae ? traeReadStatus : undefined,
|
|
@@ -1082,31 +1092,12 @@ export function apply(ctx, config = {}) {
|
|
|
1082
1092
|
const list = await ready
|
|
1083
1093
|
const out = {}
|
|
1084
1094
|
for (const stack of list) {
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
*
|
|
1089
|
-
* Trae 的对话流没有任何计费字段(实测只有 metadata /
|
|
1090
|
-
* timing_cost / output / extra_info / token_usage / done
|
|
1091
|
-
* 六种事件),所以按请求累加的 credits 恒为 0。它的积分
|
|
1092
|
-
* 接口能给出累计已消耗,虽然分不到「哪次请求」,但至少
|
|
1093
|
-
* 是真实数字,比显示 0 有意义。
|
|
1094
|
-
*
|
|
1095
|
-
* 用缓存(不强制刷新)以免打开用量页就打一轮上游。
|
|
1096
|
-
*/
|
|
1097
|
-
const credits = await stack.loadCredits().catch(() => ({}))
|
|
1098
|
-
let consumedTotal = 0
|
|
1099
|
-
let hasConsumed = false
|
|
1100
|
-
for (const account of Object.values(credits)) {
|
|
1101
|
-
if (typeof account?.consumed === 'number') {
|
|
1102
|
-
consumedTotal += account.consumed
|
|
1103
|
-
hasConsumed = true
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1095
|
+
// 只给「本页时间窗口内按请求累加」这一种口径。
|
|
1096
|
+
// 上游不逐次上报时(Trae),该指标没有真实数据可展示——
|
|
1097
|
+
// 界面据此隐藏它,而不是显示恒为 0 的数字。
|
|
1106
1098
|
out[stack.region] = {
|
|
1107
|
-
...snapshot,
|
|
1108
|
-
|
|
1109
|
-
upstreamConsumed: hasConsumed ? Math.round(consumedTotal * 100) / 100 : undefined,
|
|
1099
|
+
...stack.usage.snapshot(hours),
|
|
1100
|
+
reportsPerRequestCredits: stack.reportsPerRequestCredits,
|
|
1110
1101
|
}
|
|
1111
1102
|
}
|
|
1112
1103
|
json(res, 200, { ok: true, regions: out })
|
package/lib/trae-upstream.js
CHANGED
|
@@ -421,15 +421,14 @@ export async function fetchCredits(credential) {
|
|
|
421
421
|
const consumed = Number(summary?.consumed_amount)
|
|
422
422
|
if (Number.isFinite(totalAmount) && Number.isFinite(consumed)) {
|
|
423
423
|
// 保留两位小数:桌面显示也是两位(1621.73)。
|
|
424
|
-
// size
|
|
425
|
-
//
|
|
426
|
-
//
|
|
427
|
-
//
|
|
428
|
-
//
|
|
424
|
+
// size = 总量,供界面悬停展示「总量 / 已用 / 剩余」。
|
|
425
|
+
//
|
|
426
|
+
// 不返回 consumed:Trae 的对话流没有计费字段,用量统计拿不到
|
|
427
|
+
// 单次消耗;累计值含义不同(账号总量 ≠ 本页消耗),给了只会
|
|
428
|
+
// 诱导误用,所以不提供。
|
|
429
429
|
return {
|
|
430
430
|
total: Math.round((totalAmount - consumed) * 100) / 100,
|
|
431
431
|
size: totalAmount,
|
|
432
|
-
consumed: Math.round(consumed * 100) / 100,
|
|
433
432
|
}
|
|
434
433
|
}
|
|
435
434
|
return { total: 0 }
|