From 55c876fad585f7e3846124d7f73537b46bb4def5 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 22 Jan 2026 16:09:01 +0800 Subject: [PATCH] fix: unify weekly cost key to usage:opus:* - redis.getWeeklyOpusCost: read only usage:opus:weekly:* (remove claude fallback) - weeklyClaudeCostInitService: write to usage:opus:weekly:* instead of claude Co-Authored-By: Claude Opus 4.5 --- src/models/redis.js | 9 ++------- src/services/weeklyClaudeCostInitService.js | 14 +++++++------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/models/redis.js b/src/models/redis.js index 7cc13dec..2f139d6a 100644 --- a/src/models/redis.js +++ b/src/models/redis.js @@ -1756,13 +1756,8 @@ class RedisClient { // 💰 获取本周 Opus 费用 async getWeeklyOpusCost(keyId) { const currentWeek = getWeekStringInTimezone() - const costKey = `usage:claude:weekly:${keyId}:${currentWeek}` - let cost = await this.client.get(costKey) - // 向后兼容:如果新 key 不存在,则回退读取旧的(仅 Opus 口径)周费用 key。 - if (cost === null || cost === undefined) { - const legacyKey = `usage:opus:weekly:${keyId}:${currentWeek}` - cost = await this.client.get(legacyKey) - } + const costKey = `usage:opus:weekly:${keyId}:${currentWeek}` + const cost = await this.client.get(costKey) const result = parseFloat(cost || 0) logger.debug( `💰 Getting weekly Opus cost for ${keyId}, week: ${currentWeek}, key: ${costKey}, value: ${cost}, result: ${result}` diff --git a/src/services/weeklyClaudeCostInitService.js b/src/services/weeklyClaudeCostInitService.js index ca458ea5..32b079bd 100644 --- a/src/services/weeklyClaudeCostInitService.js +++ b/src/services/weeklyClaudeCostInitService.js @@ -31,16 +31,16 @@ class WeeklyClaudeCostInitService { return dates } - _buildWeeklyClaudeKey(keyId, weekString) { - return `usage:claude:weekly:${keyId}:${weekString}` + _buildWeeklyOpusKey(keyId, weekString) { + return `usage:opus:weekly:${keyId}:${weekString}` } /** - * 启动回填:把“本周(周一到今天)Claude 全模型”周费用从按日/按模型统计里反算出来, - * 写入 `usage:claude:weekly:*`,保证周限额在重启后不归零。 + * 启动回填:把"本周(周一到今天)Claude 全模型"周费用从按日/按模型统计里反算出来, + * 写入 `usage:opus:weekly:*`,保证周限额在重启后不归零。 * * 说明: - * - 只回填本周,不做历史回填(符合“只要本周数据”诉求) + * - 只回填本周,不做历史回填(符合"只要本周数据"诉求) * - 会加分布式锁,避免多实例重复跑 * - 会写 done 标记:同一周内重启默认不重复回填(需要时可手动删掉 done key) */ @@ -175,14 +175,14 @@ class WeeklyClaudeCostInitService { } while (cursor !== '0') } - // 为所有 API Key 写入本周 claude:weekly key,避免读取时回退到旧 opus:weekly 造成口径混淆。 + // 为所有 API Key 写入本周 opus:weekly key const ttlSeconds = 14 * 24 * 3600 const batchSize = 500 for (let i = 0; i < keyIds.length; i += batchSize) { const batch = keyIds.slice(i, i + batchSize) const pipeline = client.pipeline() for (const keyId of batch) { - const weeklyKey = this._buildWeeklyClaudeKey(keyId, weekString) + const weeklyKey = this._buildWeeklyOpusKey(keyId, weekString) const cost = costByKeyId.get(keyId) || 0 pipeline.set(weeklyKey, String(cost)) pipeline.expire(weeklyKey, ttlSeconds)