@feiyang666/dsh-usage-plugin 1.11.0 → 1.11.1
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/CHANGELOG.md +8 -0
- package/lib/client.js +32 -10
- package/package.json +1 -1
- package/scripts/release.mjs +3 -3
- package/scripts/upload-asset.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
+
## v1.11.1 (2026-08-23)
|
|
27
|
+
|
|
28
|
+
- **修复:数据加载后页面空白**:加载动画三目分支误用逗号表达式,只返回最后一个表达式值(`null`),导致加载完成后各子视图全部不渲染;改为将四个子视图作为容器 `div` 的并列子元素,加载完成后正常显示。
|
|
29
|
+
- **计费说明改为面板级固定显示**:「高峰 / 空闲时段说明」固定在用量面板子页签下方,概览、用量日历、缓存命中列表、价格表四个页面切换时始终可见(含数据加载期间)。
|
|
30
|
+
- **当前时段精确显示**:用量面板顶部徽标与价格表页顶部新增「当前 · 工作日高峰时段 / 工作日空闲时段 / 周末空闲时段」动态状态并附说明文字;周末(自 2026-08-23 起)全天按空闲价计费,规则生效前仍按原规则区分。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
26
34
|
## v1.11.0 (2026-08-23)
|
|
27
35
|
|
|
28
36
|
- **高峰 / 空闲时段说明**:概览、用量日历、缓存命中列表、价格表四个页面顶部统一新增「高峰 / 空闲时段说明」,清楚区分**工作日高峰**(周一至周五 9:00–12:00、14:00–18:00)、**工作日空闲**(其余时间)与**周末全天空闲**(自 2026-08-23 起按空闲价,此前仍按原规则)。
|
package/lib/client.js
CHANGED
|
@@ -82,6 +82,7 @@ window.__ModuleLoader__.load({
|
|
|
82
82
|
selDayTitle: { fontSize: fs(13), fontWeight: 600, marginTop: 14 },
|
|
83
83
|
billHint: { border: "1px solid rgba(90,140,255,.35)", background: "rgba(90,140,255,.08)", borderRadius: 8, padding: "10px 14px", marginTop: 10, fontSize: fs(12), lineHeight: 1.9 },
|
|
84
84
|
billHintTitle: { fontWeight: 600, marginBottom: 4, color: "#5a8cff" },
|
|
85
|
+
nowPeriod: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", marginTop: 10, fontSize: fs(12) },
|
|
85
86
|
loading: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 12, padding: "48px 0", color: "inherit" },
|
|
86
87
|
spinner: { width: 28, height: 28, borderRadius: "50%", border: "3px solid rgba(90,140,255,.22)", borderTopColor: "#5a8cff", animation: "dshUsageSpin .8s linear infinite", flexShrink: 0 },
|
|
87
88
|
loadText: { fontSize: fs(12), opacity: 0.65 }
|
|
@@ -141,6 +142,24 @@ window.__ModuleLoader__.load({
|
|
|
141
142
|
var t = d.getUTCHours() * 60 + d.getUTCMinutes();
|
|
142
143
|
return (t >= 9 * 60 && t < 12 * 60) || (t >= 14 * 60 && t < 18 * 60);
|
|
143
144
|
};
|
|
145
|
+
// 返回当前计费时段 { peak, label, desc },区分:工作日高峰 / 工作日空闲 / 周末空闲(周末自 2026-08-23 起全天按空闲价)
|
|
146
|
+
var periodNow = function (ts) {
|
|
147
|
+
ts = ts || Date.now();
|
|
148
|
+
var d = new Date(ts + 8 * 3600 * 1000);
|
|
149
|
+
var wd = d.getUTCDay(); // 0=周日 1=周一 … 6=周六
|
|
150
|
+
var isWeekend = wd === 0 || wd === 6;
|
|
151
|
+
var t = d.getUTCHours() * 60 + d.getUTCMinutes();
|
|
152
|
+
var inPeakHours = (t >= 9 * 60 && t < 12 * 60) || (t >= 14 * 60 && t < 18 * 60);
|
|
153
|
+
if (isWeekend) {
|
|
154
|
+
if (ts >= WEEKEND_FLAT_AT) return { peak: false, label: "周末空闲时段", desc: "周末(周六、周日)全天按空闲价计费" };
|
|
155
|
+
return inPeakHours
|
|
156
|
+
? { peak: true, label: "周末高峰时段", desc: "2026-08-23 前仍按原规则分峰谷" }
|
|
157
|
+
: { peak: false, label: "周末空闲时段", desc: "2026-08-23 前仍按原规则分峰谷" };
|
|
158
|
+
}
|
|
159
|
+
return inPeakHours
|
|
160
|
+
? { peak: true, label: "工作日高峰时段", desc: "周一至周五 9:00–12:00、14:00–18:00" }
|
|
161
|
+
: { peak: false, label: "工作日空闲时段", desc: "工作日其余时间" };
|
|
162
|
+
};
|
|
144
163
|
// 计费档位选择:auto 用 autoCost(按生效日期自动切换),base 用 baseCost,其余用 peakValleyCost
|
|
145
164
|
// 计费档位显示文案
|
|
146
165
|
var regimeLabel = function (regime) {
|
|
@@ -592,7 +611,6 @@ window.__ModuleLoader__.load({
|
|
|
592
611
|
function setCustomTo(v) { setToDate(v); setPreset("custom"); }
|
|
593
612
|
|
|
594
613
|
return el("div", null,
|
|
595
|
-
el(BillingHint, null),
|
|
596
614
|
el("div", { style: st.calBar },
|
|
597
615
|
el("div", { style: st.seg },
|
|
598
616
|
presetBtn("today", "今天"), presetBtn("7d", "近7天"), presetBtn("30d", "近30天"), presetBtn("all", "全部")
|
|
@@ -774,7 +792,6 @@ window.__ModuleLoader__.load({
|
|
|
774
792
|
function goToday() { setYm({ y: nowY, m: nowM }); setSelectedDay(bjKey(Date.now())); }
|
|
775
793
|
|
|
776
794
|
return el("div", null,
|
|
777
|
-
el(BillingHint, null),
|
|
778
795
|
el("div", { style: st.calBar },
|
|
779
796
|
el("button", { style: st.btn, onClick: prevMonth }, "‹ 上月"),
|
|
780
797
|
el("span", { style: { fontSize: fs(14), fontWeight: 600, minWidth: 120, textAlign: "center" } }, y + "年" + (m + 1) + "月"),
|
|
@@ -924,7 +941,6 @@ window.__ModuleLoader__.load({
|
|
|
924
941
|
var sums = splitTotals(filtered, regime);
|
|
925
942
|
|
|
926
943
|
return el("div", null,
|
|
927
|
-
el(BillingHint, null),
|
|
928
944
|
el("div", { style: st.calBar },
|
|
929
945
|
el("div", { style: st.seg },
|
|
930
946
|
presetBtn("today", "今天"), presetBtn("7d", "近7天"), presetBtn("30d", "近30天"), presetBtn("all", "全部")
|
|
@@ -1041,7 +1057,10 @@ window.__ModuleLoader__.load({
|
|
|
1041
1057
|
});
|
|
1042
1058
|
|
|
1043
1059
|
return el("div", null,
|
|
1044
|
-
el(
|
|
1060
|
+
el("div", { style: st.nowPeriod },
|
|
1061
|
+
el("span", { style: periodNow().peak ? st.badgePeak : st.badgeValley }, "当前 · " + periodNow().label),
|
|
1062
|
+
el("span", { style: st.sub }, periodNow().desc)
|
|
1063
|
+
),
|
|
1045
1064
|
el("div", { style: st.sec }, "今日 $ / ¥ 汇率"),
|
|
1046
1065
|
el("div", { style: st.cards, marginTop: 8 },
|
|
1047
1066
|
el(Card, { label: "$ → ¥", value: fx.rate ? ("$1 = ¥" + Number(fx.rate).toFixed(4)) : "暂不可用", hint: fx.date ? ("汇率日期 " + fx.date) : "等待获取" }),
|
|
@@ -1232,7 +1251,7 @@ window.__ModuleLoader__.load({
|
|
|
1232
1251
|
|
|
1233
1252
|
var records = data.records || [];
|
|
1234
1253
|
var dataPath = data.dataPath || "";
|
|
1235
|
-
var
|
|
1254
|
+
var nowPeriod = periodNow(Date.now());
|
|
1236
1255
|
var effectiveAt = data.effectiveAt || 0;
|
|
1237
1256
|
var nowEffective = effectiveAt ? (Date.now() >= effectiveAt) : true;
|
|
1238
1257
|
return el("div", { style: st.root },
|
|
@@ -1243,7 +1262,7 @@ window.__ModuleLoader__.load({
|
|
|
1243
1262
|
el("div", { style: st.title }, "用量与消耗"),
|
|
1244
1263
|
el("div", { style: st.sub }, "记录插件激活后的每一次模型调用")
|
|
1245
1264
|
),
|
|
1246
|
-
el("span", { style:
|
|
1265
|
+
el("span", { style: nowPeriod.peak ? st.badgePeak : st.badgeValley }, "当前 · " + nowPeriod.label),
|
|
1247
1266
|
el("span", { style: nowEffective ? st.badgeHit : st.badgeValley }, nowEffective ? "新价格已生效" : "新价格未生效")
|
|
1248
1267
|
),
|
|
1249
1268
|
el("div", { style: st.actions },
|
|
@@ -1260,15 +1279,18 @@ window.__ModuleLoader__.load({
|
|
|
1260
1279
|
}, t.t);
|
|
1261
1280
|
})
|
|
1262
1281
|
),
|
|
1282
|
+
el(BillingHint, null),
|
|
1263
1283
|
el("div", { style: st.note, marginTop: 6 },
|
|
1264
1284
|
"计价说明:DeepSeek 官方与 SiliconFlow 按人民币价格;DigitalOcean 按美元官方价 × USD/CNY 汇率折算人民币;千问暂不计费;AMD GPU Cloud DeepSeek V4 Flash 免费按 ¥0。"
|
|
1265
1285
|
),
|
|
1266
1286
|
loading
|
|
1267
1287
|
? el(LoadingView, null)
|
|
1268
|
-
: (
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1288
|
+
: el("div", null,
|
|
1289
|
+
tab === "overview" ? el(OverviewView, { records: records, regime: "auto" }) : null,
|
|
1290
|
+
tab === "calendar" ? el(CalendarView, { records: records, regime: "auto", days: data.days || [] }) : null,
|
|
1291
|
+
tab === "cache" ? el(CacheListView, { records: records, regime: "auto" }) : null,
|
|
1292
|
+
tab === "prices" ? el(PriceView, { pricing: data.pricing, effectiveAt: data.effectiveAt, fx: data.fx || {}, onFxRefresh: function () { api({ action: "fxRefresh" }).then(refresh).catch(function () {}); }, onChanged: refresh }) : null
|
|
1293
|
+
),
|
|
1272
1294
|
el("div", { style: st.actions, marginTop: 4 },
|
|
1273
1295
|
el("button", { style: st.btn, onClick: function () { doExport("csv"); } }, "导出 CSV"),
|
|
1274
1296
|
el("button", { style: st.btn, onClick: function () { doExport("json"); } }, "导出 JSON"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feiyang666/dsh-usage-plugin",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.1",
|
|
4
4
|
"description": "DeepSeek Harness usage & cost tracker plugin: per-call token/cache-hit stats, peak/off-peak billing, DeepSeek balance query, CSV/JSON/PNG export with custom destination, and persistent local storage. Ships a host half plus a web client half in one npm package; installs into a DSH profile as a dsh.bundle with one command (dsh plugin --profile web add @feiyang666/dsh-usage-plugin).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek",
|
package/scripts/release.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import fs from 'node:fs'
|
|
|
4
4
|
import path from 'node:path'
|
|
5
5
|
|
|
6
6
|
const REPO = 'feiyang-dev/dsh-usage-plugin'
|
|
7
|
-
const TAG = 'v1.11.
|
|
7
|
+
const TAG = 'v1.11.1'
|
|
8
8
|
|
|
9
9
|
function getCredential() {
|
|
10
10
|
const input = 'protocol=https\nhost=github.com\n\n'
|
|
@@ -76,9 +76,9 @@ if (created.status !== 201) {
|
|
|
76
76
|
const release = JSON.parse(created.body)
|
|
77
77
|
console.log('release id:', release.id, 'url:', release.html_url)
|
|
78
78
|
|
|
79
|
-
// 打包并上传 tarball 作为附件(Windows 下 npm
|
|
79
|
+
// 打包并上传 tarball 作为附件(Windows 下 npm 为 npm.cmd 批处理脚本,需经 shell 执行)
|
|
80
80
|
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'
|
|
81
|
-
const pack = spawnSync(npmCmd, ['pack'], { encoding: 'utf8' })
|
|
81
|
+
const pack = spawnSync(npmCmd, ['pack'], { encoding: 'utf8', shell: process.platform === 'win32' })
|
|
82
82
|
const tgzName = (pack.stdout || '').trim().split('\n').pop()
|
|
83
83
|
if (tgzName && fs.existsSync(tgzName)) {
|
|
84
84
|
const buf = fs.readFileSync(tgzName)
|
package/scripts/upload-asset.mjs
CHANGED