mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 09:38:02 +00:00
fix: 🐛 fee calc fix
This commit is contained in:
@@ -947,9 +947,46 @@ class ApiKeyService {
|
|||||||
await pricingService.initialize()
|
await pricingService.initialize()
|
||||||
}
|
}
|
||||||
costInfo = pricingService.calculateCost(usageObject, model)
|
costInfo = pricingService.calculateCost(usageObject, model)
|
||||||
|
|
||||||
|
// 验证计算结果
|
||||||
|
if (!costInfo || typeof costInfo.totalCost !== 'number') {
|
||||||
|
logger.error(`❌ Invalid cost calculation result for model ${model}:`, costInfo)
|
||||||
|
// 使用 CostCalculator 作为后备
|
||||||
|
const CostCalculator = require('../utils/costCalculator')
|
||||||
|
const fallbackCost = CostCalculator.calculateCost(usageObject, model)
|
||||||
|
if (fallbackCost && fallbackCost.costs && fallbackCost.costs.total > 0) {
|
||||||
|
logger.warn(
|
||||||
|
`⚠️ Using fallback cost calculation for ${model}: $${fallbackCost.costs.total}`
|
||||||
|
)
|
||||||
|
costInfo = {
|
||||||
|
totalCost: fallbackCost.costs.total,
|
||||||
|
ephemeral5mCost: 0,
|
||||||
|
ephemeral1hCost: 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
costInfo = { totalCost: 0, ephemeral5mCost: 0, ephemeral1hCost: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (pricingError) {
|
} catch (pricingError) {
|
||||||
logger.error('❌ Failed to calculate cost:', pricingError)
|
logger.error(`❌ Failed to calculate cost for model ${model}:`, pricingError)
|
||||||
// 继续执行,不要因为费用计算失败而跳过统计记录
|
logger.error(` Usage object:`, JSON.stringify(usageObject))
|
||||||
|
// 使用 CostCalculator 作为后备
|
||||||
|
try {
|
||||||
|
const CostCalculator = require('../utils/costCalculator')
|
||||||
|
const fallbackCost = CostCalculator.calculateCost(usageObject, model)
|
||||||
|
if (fallbackCost && fallbackCost.costs && fallbackCost.costs.total > 0) {
|
||||||
|
logger.warn(
|
||||||
|
`⚠️ Using fallback cost calculation for ${model}: $${fallbackCost.costs.total}`
|
||||||
|
)
|
||||||
|
costInfo = {
|
||||||
|
totalCost: fallbackCost.costs.total,
|
||||||
|
ephemeral5mCost: 0,
|
||||||
|
ephemeral1hCost: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (fallbackError) {
|
||||||
|
logger.error(`❌ Fallback cost calculation also failed:`, fallbackError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提取详细的缓存创建数据
|
// 提取详细的缓存创建数据
|
||||||
@@ -994,7 +1031,15 @@ class ApiKeyService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.debug(`💰 No cost recorded for ${keyId} - zero cost for model: ${model}`)
|
// 如果有 token 使用但费用为 0,记录警告
|
||||||
|
if (totalTokens > 0) {
|
||||||
|
logger.warn(
|
||||||
|
`⚠️ No cost recorded for ${keyId} - zero cost for model: ${model} (tokens: ${totalTokens})`
|
||||||
|
)
|
||||||
|
logger.warn(` This may indicate a pricing issue or model not found in pricing data`)
|
||||||
|
} else {
|
||||||
|
logger.debug(`💰 No cost recorded for ${keyId} - zero tokens for model: ${model}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取API Key数据以确定关联的账户
|
// 获取API Key数据以确定关联的账户
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ const MODEL_PRICING = {
|
|||||||
cacheWrite: 3.75,
|
cacheWrite: 3.75,
|
||||||
cacheRead: 0.3
|
cacheRead: 0.3
|
||||||
},
|
},
|
||||||
|
'claude-sonnet-4-5-20250929': {
|
||||||
|
input: 3.0,
|
||||||
|
output: 15.0,
|
||||||
|
cacheWrite: 3.75,
|
||||||
|
cacheRead: 0.3
|
||||||
|
},
|
||||||
|
|
||||||
// Claude 3.5 Haiku
|
// Claude 3.5 Haiku
|
||||||
'claude-3-5-haiku-20241022': {
|
'claude-3-5-haiku-20241022': {
|
||||||
|
|||||||
@@ -92,11 +92,19 @@ export const useApiStatsStore = defineStore('apistats', () => {
|
|||||||
return queryBatchStats()
|
return queryBatchStats()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!apiKey.value.trim()) {
|
const trimmedKey = apiKey.value.trim()
|
||||||
|
|
||||||
|
if (!trimmedKey) {
|
||||||
error.value = '请输入 API Key'
|
error.value = '请输入 API Key'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 验证 API Key 格式:长度应在 10-512 之间
|
||||||
|
if (trimmedKey.length < 10 || trimmedKey.length > 512) {
|
||||||
|
error.value = 'API Key 格式无效:长度应在 10-512 个字符之间'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
error.value = ''
|
error.value = ''
|
||||||
statsData.value = null
|
statsData.value = null
|
||||||
@@ -105,7 +113,7 @@ export const useApiStatsStore = defineStore('apistats', () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取 API Key ID
|
// 获取 API Key ID
|
||||||
const idResult = await apiStatsClient.getKeyId(apiKey.value)
|
const idResult = await apiStatsClient.getKeyId(trimmedKey)
|
||||||
|
|
||||||
if (idResult.success) {
|
if (idResult.success) {
|
||||||
apiId.value = idResult.data.id
|
apiId.value = idResult.data.id
|
||||||
@@ -431,7 +439,7 @@ export const useApiStatsStore = defineStore('apistats', () => {
|
|||||||
const keys = apiKey.value
|
const keys = apiKey.value
|
||||||
.split(/[,\n]+/)
|
.split(/[,\n]+/)
|
||||||
.map((key) => key.trim())
|
.map((key) => key.trim())
|
||||||
.filter((key) => key.length > 0)
|
.filter((key) => key.length >= 10 && key.length <= 512) // 验证 API Key 格式
|
||||||
|
|
||||||
// 去重并限制最多30个
|
// 去重并限制最多30个
|
||||||
const uniqueKeys = [...new Set(keys)]
|
const uniqueKeys = [...new Set(keys)]
|
||||||
|
|||||||
Reference in New Issue
Block a user