mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 09:38:02 +00:00
feat: 添加精确的账户费用计算和时区支持
- 实现基于模型使用量的精确每日费用计算 - 添加 dateHelper 工具支持时区转换 - 移除未使用的 webhook 配置代码 - 清理环境变量和配置文件中的 webhook 相关设置 - 优化前端费用显示,使用后端精确计算的数据 - 添加 DEBUG_HTTP_TRAFFIC 调试选项支持 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ const {
|
||||
} = require('../utils/tokenRefreshLogger')
|
||||
const tokenRefreshService = require('./tokenRefreshService')
|
||||
const LRUCache = require('../utils/lruCache')
|
||||
const { formatDateWithTimezone, getISOStringWithTimezone } = require('../utils/dateHelper')
|
||||
|
||||
class ClaudeAccountService {
|
||||
constructor() {
|
||||
@@ -1121,8 +1122,8 @@ class ClaudeAccountService {
|
||||
platform: 'claude-oauth',
|
||||
status: 'error',
|
||||
errorCode: 'CLAUDE_OAUTH_RATE_LIMITED',
|
||||
reason: `Account rate limited (429 error). ${rateLimitResetTimestamp ? `Reset at: ${new Date(rateLimitResetTimestamp * 1000).toISOString()}` : 'Estimated reset in 1-5 hours'}`,
|
||||
timestamp: new Date().toISOString()
|
||||
reason: `Account rate limited (429 error). ${rateLimitResetTimestamp ? `Reset at: ${formatDateWithTimezone(rateLimitResetTimestamp)}` : 'Estimated reset in 1-5 hours'}`,
|
||||
timestamp: getISOStringWithTimezone(new Date())
|
||||
})
|
||||
} catch (webhookError) {
|
||||
logger.error('Failed to send rate limit webhook notification:', webhookError)
|
||||
@@ -1322,7 +1323,7 @@ class ClaudeAccountService {
|
||||
status: 'resumed',
|
||||
errorCode: 'CLAUDE_5H_LIMIT_RESUMED',
|
||||
reason: '进入新的5小时窗口,已自动恢复调度',
|
||||
timestamp: new Date().toISOString()
|
||||
timestamp: getISOStringWithTimezone(new Date())
|
||||
})
|
||||
} catch (webhookError) {
|
||||
logger.error('Failed to send webhook notification:', webhookError)
|
||||
@@ -1985,7 +1986,7 @@ class ClaudeAccountService {
|
||||
status: 'warning',
|
||||
errorCode: 'CLAUDE_5H_LIMIT_WARNING',
|
||||
reason: '5小时使用量接近限制,已自动停止调度',
|
||||
timestamp: new Date().toISOString()
|
||||
timestamp: getISOStringWithTimezone(new Date())
|
||||
})
|
||||
} catch (webhookError) {
|
||||
logger.error('Failed to send webhook notification:', webhookError)
|
||||
|
||||
@@ -369,6 +369,7 @@ class ClaudeConsoleAccountService {
|
||||
// 发送Webhook通知
|
||||
try {
|
||||
const webhookNotifier = require('../utils/webhookNotifier')
|
||||
const { getISOStringWithTimezone } = require('../utils/dateHelper')
|
||||
await webhookNotifier.sendAccountAnomalyNotification({
|
||||
accountId,
|
||||
accountName: account.name || 'Claude Console Account',
|
||||
@@ -376,7 +377,7 @@ class ClaudeConsoleAccountService {
|
||||
status: 'error',
|
||||
errorCode: 'CLAUDE_CONSOLE_RATE_LIMITED',
|
||||
reason: `Account rate limited (429 error). ${account.rateLimitDuration ? `Will be blocked for ${account.rateLimitDuration} hours` : 'Temporary rate limit'}`,
|
||||
timestamp: new Date().toISOString()
|
||||
timestamp: getISOStringWithTimezone(new Date())
|
||||
})
|
||||
} catch (webhookError) {
|
||||
logger.error('Failed to send rate limit webhook notification:', webhookError)
|
||||
|
||||
@@ -308,7 +308,9 @@ class PricingService {
|
||||
|
||||
// 确保价格对象包含缓存价格
|
||||
ensureCachePricing(pricing) {
|
||||
if (!pricing) return pricing
|
||||
if (!pricing) {
|
||||
return pricing
|
||||
}
|
||||
|
||||
// 如果缺少缓存价格,根据输入价格计算(缓存创建价格通常是输入价格的1.25倍,缓存读取是0.1倍)
|
||||
if (!pricing.cache_creation_input_token_cost && pricing.input_cost_per_token) {
|
||||
|
||||
@@ -2,6 +2,7 @@ const axios = require('axios')
|
||||
const crypto = require('crypto')
|
||||
const logger = require('../utils/logger')
|
||||
const webhookConfigService = require('./webhookConfigService')
|
||||
const { getISOStringWithTimezone } = require('../utils/dateHelper')
|
||||
|
||||
class WebhookService {
|
||||
constructor() {
|
||||
@@ -206,7 +207,7 @@ class WebhookService {
|
||||
const payload = {
|
||||
type,
|
||||
service: 'claude-relay-service',
|
||||
timestamp: new Date().toISOString(),
|
||||
timestamp: getISOStringWithTimezone(new Date()),
|
||||
data
|
||||
}
|
||||
|
||||
@@ -357,7 +358,7 @@ class WebhookService {
|
||||
title,
|
||||
color,
|
||||
fields,
|
||||
timestamp: new Date().toISOString(),
|
||||
timestamp: getISOStringWithTimezone(new Date()),
|
||||
footer: {
|
||||
text: 'Claude Relay Service'
|
||||
}
|
||||
@@ -580,7 +581,7 @@ class WebhookService {
|
||||
try {
|
||||
const testData = {
|
||||
message: 'Claude Relay Service webhook测试',
|
||||
timestamp: new Date().toISOString()
|
||||
timestamp: getISOStringWithTimezone(new Date())
|
||||
}
|
||||
|
||||
await this.sendToPlatform(platform, 'test', testData, { maxRetries: 1, retryDelay: 1000 })
|
||||
|
||||
Reference in New Issue
Block a user