dsh-whale-widget 0.2.8 → 0.2.9

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 CHANGED
@@ -10,7 +10,7 @@ DeepSeek Harness(DSH)Web 界面右下角的常驻余额挂件:小鲸鱼气
10
10
  - 💰 **余额**:60 秒自动刷新 + 点击鲸鱼手动刷新;余额变化时数字**滚动动画**;瞬时网络抖动自动沿用最近余额不报错
11
11
  - 📊 **今日已用**:两种模式任选(见下),显示今日消耗金额
12
12
  - **小鲸鱼记账(推荐,免令牌)**:不需要任何会话令牌,鲸鱼娘每次观测余额后用余额差值自动记账(`.dshw-usage.json`,跨天自动归零归档)
13
- - **实时·令牌**:填入平台会话令牌后直接调用平台用量接口,按**峰谷定价**(空闲 9:00–12:00 与 14:00–18:00 之外 / 高峰 9–12 与 14–18 点)实时换算今日已用
13
+ - **实时·令牌**:填入平台会话令牌后直接调用平台用量接口,按**峰谷定价**(工作日高峰 9:00–12:00 与 14:00–18:00,其余空闲;2026-08-23 起周末全天按谷价)实时换算今日已用
14
14
  - 💬 **每轮对话消耗统计**:监听本机会话事件,每轮对话结束后弹出本轮消耗金额(精确 usage,非估算)
15
15
  - 菜单可开关「每轮对话后自动显示消耗金额」;「自动关闭时间」可自定义秒数(填 0 表示不自动关闭)
16
16
  - 消耗金额泡泡显示期间,余额变动不弹普通泡泡
@@ -146,7 +146,7 @@ Remove-Item "$web\DSniang02.png" -ErrorAction SilentlyContinue
146
146
 
147
147
  **① 小鲸鱼记账(推荐,默认)—— 完全不需要额外配置**
148
148
 
149
- 鲸鱼娘自己用**余额差值**记账:每次观测到余额下降就把差值累加到当天用量,跨天自动归零归档(保留 30 天)。只要配好了 `DEEPSEEK_API_KEY` 就能用,**开箱即用**。
149
+ 鲸鱼娘自己用**余额差值**记账:每次观测到余额下降就把差值累加到当天用量,跨天自动归零归档(保留 30 天);观测币种发生变化时只重置基准、不记差值(防止多币种账户切换污染账本)。只要配好了 `DEEPSEEK_API_KEY` 就能用,**开箱即用**。
150
150
 
151
151
  - 账本文件:`$DSH_HOME/.dshw-usage.json`(自动生成)
152
152
  - 优点:零配置、免令牌
package/lib/index.js CHANGED
@@ -63,7 +63,8 @@ const RUA_GIF_CANDIDATES = [
63
63
  'D:/TestBox/deepseek/rua.gif',
64
64
  ]
65
65
  // DeepSeek CNY prices per million tokens: [空闲时段价, 高峰时段价].
66
- // 高峰时段:每日 9:00–12:00 和 14:00–18:00(北京时间)。Adjust here if DeepSeek changes pricing.
66
+ // 高峰时段:工作日 9:00–12:00 和 14:00–18:00(北京时间);2026-08-23 起周末全天谷价。
67
+ // Adjust here if DeepSeek changes pricing.
67
68
  const PEAK_HOURS = [
68
69
  [9, 12],
69
70
  [14, 18],
@@ -88,9 +89,18 @@ function priceFor(model) {
88
89
  return PRICING._default
89
90
  }
90
91
  // bucket time is an epoch second; derive the Beijing local hour to pick peak vs off-peak price.
92
+ // 2026-08-23 起(北京时间)周末(周六/周日)全天按谷价;生效时刻之前的历史
93
+ // 分桶仍按旧规则计价,所以周末判定带生效分界。
94
+ const WEEKEND_VALLEY_FROM_SEC = Math.floor(Date.UTC(2026, 7, 22, 16, 0, 0) / 1000) // = 北京时间 2026-08-23 00:00
91
95
  function isPeakTime(timeSec) {
92
96
  if (!isFinite(Number(timeSec))) return false
93
- const hour = new Date(Number(timeSec) * 1000 + 8 * 3600 * 1000).getUTCHours()
97
+ const n = Number(timeSec)
98
+ const bj = new Date(n * 1000 + 8 * 3600 * 1000)
99
+ if (n >= WEEKEND_VALLEY_FROM_SEC) {
100
+ const dow = bj.getUTCDay() // 0=周日 6=周六(bj 按 UTC 读即为北京日历日)
101
+ if (dow === 0 || dow === 6) return false
102
+ }
103
+ const hour = bj.getUTCHours()
94
104
  for (const [start, end] of PEAK_HOURS) {
95
105
  if (hour >= start && hour < end) return true
96
106
  }
@@ -611,6 +621,10 @@ function showCostBubble(amount) {
611
621
  if (costBubbleTimer) { clearTimeout(costBubbleTimer); costBubbleTimer = null }
612
622
  if (bubbleTimer) { clearTimeout(bubbleTimer); bubbleTimer = null }
613
623
  if (gifFadeTimer) { clearTimeout(gifFadeTimer); gifFadeTimer = null }
624
+ // 取消进行中的余额数字滚动与延迟计时器,避免竞态覆盖成本金额
625
+ if (animId) { cancelAnimationFrame(animId); animId = null }
626
+ if (animDelayTimer) { clearTimeout(animDelayTimer); animDelayTimer = null }
627
+ if (settleTimer) { clearTimeout(settleTimer); settleTimer = null }
614
628
  costBubbleActive = true
615
629
  bubbleRandomActive = false
616
630
  bubbleShown = true
@@ -672,6 +686,11 @@ function animateAmount(from, to, currency, duration) {
672
686
  }
673
687
  var startTime = null
674
688
  function step(ts) {
689
+ // 帧级保护:成本泡泡出现后立即停止滚动,避免后续帧把余额写进金额行
690
+ if (costBubbleActive) {
691
+ animId = null
692
+ return
693
+ }
675
694
  if (startTime === null) startTime = ts
676
695
  var t = Math.min(1, (ts - startTime) / duration)
677
696
  var eased = 1 - Math.pow(1 - t, 3)
@@ -1640,10 +1659,16 @@ function apply(ctx) {
1640
1659
  }
1641
1660
  return false
1642
1661
  }
1643
- // 记账模式:每次观测到余额后,用余额正差值累计当天用量(跨天自动归零并归档)
1644
- function recordLedgerUsage(currentBalance) {
1662
+ // 记账模式:每次观测到余额后,用余额正差值累计当天用量(跨天自动归零并归档)。
1663
+ // 币种感知:观测币种与上次不同时只重置基准、不记差值——数值跳变来自币种
1664
+ // 切换而非真实消费([0] 选币时代 CNY/USD 随机切换曾记出巨额假账,见 #13)。
1665
+ function recordLedgerUsage(currentBalance, currency) {
1645
1666
  const t = todayKey()
1646
1667
  let led = readUsageLedger()
1668
+ const cur = String(currency || '')
1669
+ const currencyChanged =
1670
+ typeof led.lastCurrency === 'string' && led.lastCurrency !== '' &&
1671
+ cur !== '' && led.lastCurrency !== cur
1647
1672
  if (led.date !== t) {
1648
1673
  if (led.date && typeof led.todayUsage === 'number') {
1649
1674
  led.history = led.history || {}
@@ -1651,13 +1676,19 @@ function apply(ctx) {
1651
1676
  }
1652
1677
  led.date = t
1653
1678
  led.lastBalance = currentBalance
1679
+ led.lastCurrency = cur
1654
1680
  led.todayUsage = 0
1681
+ } else if (currencyChanged) {
1682
+ // 币种切换:只换基准,不把差值记成消费
1683
+ led.lastBalance = currentBalance
1684
+ led.lastCurrency = cur
1655
1685
  } else {
1656
1686
  const prev = typeof led.lastBalance === 'number' ? led.lastBalance : currentBalance
1657
1687
  if (typeof prev === 'number' && typeof currentBalance === 'number' && currentBalance < prev) {
1658
1688
  led.todayUsage = (typeof led.todayUsage === 'number' ? led.todayUsage : 0) + (prev - currentBalance)
1659
1689
  }
1660
1690
  led.lastBalance = currentBalance
1691
+ led.lastCurrency = cur
1661
1692
  }
1662
1693
  const keys = Object.keys(led.history || {}).sort()
1663
1694
  while (keys.length > 30) {
@@ -1674,7 +1705,7 @@ function apply(ctx) {
1674
1705
  const payload = await fetchBalance()
1675
1706
  if (!payload.ok) return payload
1676
1707
  // 无论哪种模式,都先把余额观测记入账本(自动累积「鲸鱼记账」数据)
1677
- const led = recordLedgerUsage(Number(payload.totalBalance))
1708
+ const led = recordLedgerUsage(Number(payload.totalBalance), payload.currency)
1678
1709
  const cfg = readSizeConfig() || {}
1679
1710
  const mode = normalizeUsageMode(cfg.usageMode)
1680
1711
  const full = { ...payload }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-whale-widget",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "DSH Web 界面右下角的 DeepSeek 余额小鲸鱼挂件(含今日已用、峰谷定价、随机台词、音效与每轮消耗统计)",
5
5
  "keywords": [
6
6
  "dsh",