/** * Token 使用量处理器 * * 从远程 API 获取数据,筛选 Opus/Thinking 模型,并存储历史记录 */ import { usageHistoryTable } from '@/db/schema' import { env } from '@/env' import { dbProvider } from '@/orpc/middlewares' import { os } from '@/orpc/server' /** 远程 API 响应中的账户数据结构 */ interface RemoteAccountData { accountName: string remainingFraction: number resetTime?: string status?: string } /** 远程 API 响应中的模型数据结构 (按模型分组) */ interface RemoteModelData { modelId: string displayName?: string accounts: RemoteAccountData[] } /** 远程 API 响应结构 */ interface RemoteResponse { data: RemoteModelData[] } export const getUsage = os.usage.getUsage .use(dbProvider) .handler(async ({ context }) => { // 1. 获取远程数据 const response = await fetch(env.TOKEN_USAGE_URL) if (!response.ok) { throw new Error(`Failed to fetch usage data: ${response.statusText}`) } const data = (await response.json()) as RemoteResponse // 2. 找到 claude-opus-4-5-thinking 模型,然后从其 accounts 中提取数据 const opusModels: Array<{ account: string model: string displayName?: string remainingFraction: number resetTime?: string }> = [] // 新 API 按模型分组,找到目标模型 const opusModelData = data.data.find( (m) => m.modelId === 'claude-opus-4-5-thinking', ) if (opusModelData) { // 遍历该模型下的所有账户 for (const accountData of opusModelData.accounts) { const account = accountData.accountName.replace('.json', '') opusModels.push({ account, model: opusModelData.modelId, displayName: opusModelData.displayName, remainingFraction: accountData.remainingFraction, resetTime: accountData.resetTime, }) } } // 3. 存储到历史表(仅在 Bun 环境下工作) try { if (opusModels.length > 0 && context.db) { await context.db.insert(usageHistoryTable).values( opusModels.map((m) => ({ account: m.account, model: m.model, displayName: m.displayName, remainingFraction: m.remainingFraction, resetTime: m.resetTime, })), ) } } catch (err) { // 在非 Bun 环境下,数据库可能不可用,忽略错误 console.warn('Database insert skipped:', err) } return { opusModels, fetchedAt: new Date().toISOString(), } })