import { query } from "./db"; import { CACHE_CREATION, CACHE_READ, REAL_MODEL, cacheKey, cached, timeWhere } from "./query-shared"; // ── 总览 ────────────────────────────────────────────────────── export interface OverviewData { total_calls: number; total_tokens: number; total_prompt: number; total_completion: number; total_cache_creation: number; total_cache_read: number; total_quota: number; active_users: number; active_models: number; active_channels: number; } export function getOverview( startTs?: number, endTs?: number ): Promise { return cached(cacheKey("overview", startTs, endTs), async () => { const params: (string | number | boolean | null)[] = []; const where = timeWhere(params, startTs, endTs); const rows = await query( `SELECT COUNT(*)::int as total_calls, COALESCE(SUM(prompt_tokens + completion_tokens), 0)::bigint as total_tokens, COALESCE(SUM(prompt_tokens), 0)::bigint as total_prompt, COALESCE(SUM(completion_tokens), 0)::bigint as total_completion, COALESCE(SUM(${CACHE_CREATION}), 0)::bigint as total_cache_creation, COALESCE(SUM(${CACHE_READ}), 0)::bigint as total_cache_read, COALESCE(SUM(quota), 0)::bigint as total_quota, COUNT(DISTINCT user_id)::int as active_users, COUNT(DISTINCT ${REAL_MODEL})::int as active_models, COUNT(DISTINCT channel_id)::int as active_channels FROM logs WHERE ${where}`, params ); const r = rows[0]; return { total_calls: Number(r.total_calls), total_tokens: Number(r.total_tokens) + Number(r.total_cache_creation) + Number(r.total_cache_read), total_prompt: Number(r.total_prompt), total_completion: Number(r.total_completion), total_cache_creation: Number(r.total_cache_creation), total_cache_read: Number(r.total_cache_read), total_quota: Number(r.total_quota), active_users: Number(r.active_users), active_models: Number(r.active_models), active_channels: Number(r.active_channels), }; }); }