- 使用 shadcn/ui 重新实现 TopBar、ThemeSidebar、AlertBadge 组件 - 解决 @oicl/openbridge-webcomponents ESM 模块解析问题 - 添加 OpenBridge 四种主题 CSS 变量 (day/bright/dusk/night) - Night 主题使用暗黄色文字保护夜视能力 - 更新 API 端点适配新的按模型分组数据结构
93 lines
2.5 KiB
TypeScript
93 lines
2.5 KiB
TypeScript
/**
|
|
* 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(),
|
|
}
|
|
})
|