🏁 Final commit: Project Token Usage Viewer completed
This commit is contained in:
84
src/orpc/handlers/usage.ts
Normal file
84
src/orpc/handlers/usage.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 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 RemoteModelData {
|
||||
model: string
|
||||
displayName?: string
|
||||
remainingFraction: number
|
||||
resetTime?: string
|
||||
}
|
||||
|
||||
/** 远程 API 响应结构 */
|
||||
interface RemoteResponse {
|
||||
result: Record<string, 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 模型
|
||||
const opusModels: Array<{
|
||||
account: string
|
||||
model: string
|
||||
displayName?: string
|
||||
remainingFraction: number
|
||||
resetTime?: string
|
||||
}> = []
|
||||
|
||||
for (const [accountFile, models] of Object.entries(data.result)) {
|
||||
const account = accountFile.replace('.json', '')
|
||||
|
||||
// 只找 claude-opus-4-5-thinking 模型
|
||||
const opusModel = models.find(
|
||||
(m) => m.model === 'claude-opus-4-5-thinking',
|
||||
)
|
||||
|
||||
if (opusModel) {
|
||||
opusModels.push({
|
||||
account,
|
||||
model: opusModel.model,
|
||||
displayName: opusModel.displayName,
|
||||
remainingFraction: opusModel.remainingFraction,
|
||||
resetTime: opusModel.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(),
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user