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 <noreply@anthropic.com>
This commit is contained in:
root
2026-01-22 16:09:01 +08:00
parent f9df276d0c
commit 55c876fad5
2 changed files with 9 additions and 14 deletions

View File

@@ -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}`

View File

@@ -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)