Files
claude-relay-service/assets/DashboardView-Cv0OIh9M.js
2025-08-08 12:39:58 +00:00

2 lines
35 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{E as Tt}from"./element-plus-B8Fs_0jW.js";import{aR as Ct,r as _,c as _t,aW as wt,o as mt,q as St,D as ot,V as Rt,x as v,z as t,P as p,u as s,L as P,O as $,Q as ht,ac as kt,C as W,R as $t,K as At,al as Pt,y as h}from"./vue-vendor-CKToUHZx.js";import{a as J,_ as It}from"./index-FG17xIFK.js";import{s as gt}from"./toast-BvwA7Mwb.js";import{C as bt}from"./chart-Cor9iTVD.js";import"./vendor-BDiMbLwQ.js";const Ut=Ct("dashboard",()=>{const nt=_(!1),G=_({totalApiKeys:0,activeApiKeys:0,totalAccounts:0,normalAccounts:0,abnormalAccounts:0,pausedAccounts:0,activeAccounts:0,rateLimitedAccounts:0,accountsByPlatform:{claude:{total:0,normal:0,abnormal:0,paused:0,rateLimited:0},"claude-console":{total:0,normal:0,abnormal:0,paused:0,rateLimited:0},gemini:{total:0,normal:0,abnormal:0,paused:0,rateLimited:0},bedrock:{total:0,normal:0,abnormal:0,paused:0,rateLimited:0}},todayRequests:0,totalRequests:0,todayTokens:0,todayInputTokens:0,todayOutputTokens:0,totalTokens:0,totalInputTokens:0,totalOutputTokens:0,totalCacheCreateTokens:0,totalCacheReadTokens:0,todayCacheCreateTokens:0,todayCacheReadTokens:0,systemRPM:0,systemTPM:0,realtimeRPM:0,realtimeTPM:0,metricsWindow:5,isHistoricalMetrics:!1,systemStatus:"正常",uptime:0,systemTimezone:8}),o=_({todayCosts:{totalCost:0,formatted:{totalCost:"$0.000000"}},totalCosts:{totalCost:0,formatted:{totalCost:"$0.000000"}}}),lt=_([]),H=_([]),X=_([]),I=_({data:[],topApiKeys:[],totalApiKeys:0}),l=_({type:"preset",preset:"7days",customStart:"",customEnd:"",customRange:null,presetOptions:[{value:"today",label:"今日",days:1},{value:"7days",label:"7天",days:7},{value:"30days",label:"30天",days:30}]}),w=_("day"),q=_("requests"),O=_([new Date(2e3,1,1,0,0,0),new Date(2e3,2,1,23,59,59)]),pt=_t(()=>{const d=G.value.uptime,r=Math.floor(d/86400),i=Math.floor(d%86400/3600),u=Math.floor(d%3600/60);return r>0?`${r}${i}小时`:i>0?`${i}小时 ${u}分钟`:`${u}分钟`});function T(d,r=!0){const i=d.getFullYear(),u=d.getMonth(),n=d.getDate();return r?new Date(Date.UTC(i,u,n-1,16,0,0,0)):new Date(Date.UTC(i,u,n,15,59,59,999))}async function yt(d=null){nt.value=!0;try{let r={today:"today",all:"all"};d&&(r={today:{today:"today",all:"today"},"7days":{today:"7days",all:"7days"},monthly:{today:"monthly",all:"monthly"},all:{today:"today",all:"all"}}[d]||r);const[i,u,n]=await Promise.all([J.get("/admin/dashboard"),J.get(`/admin/usage-costs?period=${r.today}`),J.get(`/admin/usage-costs?period=${r.all}`)]);if(i.success){const a=i.data.overview||{},c=i.data.recentActivity||{},m=i.data.systemAverages||{},y=i.data.realtimeMetrics||{},C=i.data.systemHealth||{};G.value={totalApiKeys:a.totalApiKeys||0,activeApiKeys:a.activeApiKeys||0,totalAccounts:a.totalAccounts||a.totalClaudeAccounts||0,normalAccounts:a.normalAccounts||0,abnormalAccounts:a.abnormalAccounts||0,pausedAccounts:a.pausedAccounts||0,activeAccounts:a.activeAccounts||a.activeClaudeAccounts||0,rateLimitedAccounts:a.rateLimitedAccounts||a.rateLimitedClaudeAccounts||0,accountsByPlatform:a.accountsByPlatform||{claude:{total:0,normal:0,abnormal:0,paused:0,rateLimited:0},"claude-console":{total:0,normal:0,abnormal:0,paused:0,rateLimited:0},gemini:{total:0,normal:0,abnormal:0,paused:0,rateLimited:0},bedrock:{total:0,normal:0,abnormal:0,paused:0,rateLimited:0}},todayRequests:c.requestsToday||0,totalRequests:a.totalRequestsUsed||0,todayTokens:c.tokensToday||0,todayInputTokens:c.inputTokensToday||0,todayOutputTokens:c.outputTokensToday||0,totalTokens:a.totalTokensUsed||0,totalInputTokens:a.totalInputTokensUsed||0,totalOutputTokens:a.totalOutputTokensUsed||0,totalCacheCreateTokens:a.totalCacheCreateTokensUsed||0,totalCacheReadTokens:a.totalCacheReadTokensUsed||0,todayCacheCreateTokens:c.cacheCreateTokensToday||0,todayCacheReadTokens:c.cacheReadTokensToday||0,systemRPM:m.rpm||0,systemTPM:m.tpm||0,realtimeRPM:y.rpm||0,realtimeTPM:y.tpm||0,metricsWindow:y.windowMinutes||5,isHistoricalMetrics:y.isHistorical||!1,systemStatus:C.redisConnected?"正常":"异常",uptime:C.uptime||0,systemTimezone:i.data.systemTimezone||8}}u.success&&n.success&&(o.value={todayCosts:u.data.totalCosts||{totalCost:0,formatted:{totalCost:"$0.000000"}},totalCosts:n.data.totalCosts||{totalCost:0,formatted:{totalCost:"$0.000000"}}})}catch(r){console.error("加载仪表板数据失败:",r)}finally{nt.value=!1}}async function rt(d=7,r="day"){try{let i="/admin/usage-trend?";if(r==="hour")if(i+="granularity=hour",l.value.customRange&&l.value.customRange.length===2){const n=a=>{const[m,y]=a.split(" "),[C,M,K]=m.split("-").map(Number),[U,F,L]=y.split(":").map(Number);return new Date(Date.UTC(C,M-1,K,U-8,F,L)).toISOString()};i+=`&startDate=${encodeURIComponent(n(l.value.customRange[0]))}`,i+=`&endDate=${encodeURIComponent(n(l.value.customRange[1]))}`}else{const n=new Date;let a,c;if(l.value.type==="preset")switch(l.value.preset){case"last24h":{c=new Date(n),a=new Date(n.getTime()-24*60*60*1e3);break}case"yesterday":{const m=new Date;m.setDate(m.getDate()-1),a=T(m,!0),c=T(m,!1);break}case"dayBefore":{const m=new Date;m.setDate(m.getDate()-2),a=T(m,!0),c=T(m,!1);break}default:a=new Date(n.getTime()-24*60*60*1e3),c=n}else a=new Date(n.getTime()-d*24*60*60*1e3),c=n;i+=`&startDate=${encodeURIComponent(a.toISOString())}`,i+=`&endDate=${encodeURIComponent(c.toISOString())}`}else i+=`granularity=day&days=${d}`;const u=await J.get(i);u.success&&(H.value=u.data)}catch(i){console.error("加载使用趋势失败:",i)}}async function it(d="daily"){try{let r=`/admin/model-stats?period=${d}`;if(l.value.type==="custom"||w.value==="hour"){if(l.value.customRange&&l.value.customRange.length===2){const u=n=>{const[c,m]=n.split(" "),[y,C,M]=c.split("-").map(Number),[K,U,F]=m.split(":").map(Number);return new Date(Date.UTC(y,C-1,M,K-8,U,F)).toISOString()};r+=`&startDate=${encodeURIComponent(u(l.value.customRange[0]))}`,r+=`&endDate=${encodeURIComponent(u(l.value.customRange[1]))}`}else if(w.value==="hour"&&l.value.type==="preset"){const u=new Date;let n,a;switch(l.value.preset){case"last24h":{a=new Date(u),n=new Date(u.getTime()-24*60*60*1e3);break}case"yesterday":{const c=new Date;c.setDate(c.getDate()-1),n=T(c,!0),a=T(c,!1);break}case"dayBefore":{const c=new Date;c.setDate(c.getDate()-2),n=T(c,!0),a=T(c,!1);break}default:n=new Date(u.getTime()-24*60*60*1e3),a=u}r+=`&startDate=${encodeURIComponent(n.toISOString())}`,r+=`&endDate=${encodeURIComponent(a.toISOString())}`}}else if(l.value.type==="preset"&&w.value==="day"){const u=new Date;let n,a;const c=l.value.presetOptions.find(m=>m.value===l.value.preset);if(c){if(l.value.preset==="today")n=T(u,!0),a=T(u,!1);else{const m=new Date;m.setDate(m.getDate()-(c.days-1)),n=T(m,!0),a=T(u,!1)}r+=`&startDate=${encodeURIComponent(n.toISOString())}`,r+=`&endDate=${encodeURIComponent(a.toISOString())}`}}const i=await J.get(r);i.success&&(X.value=i.data)}catch(r){console.error("加载模型统计失败:",r)}}async function tt(d="requests"){try{let r="/admin/api-keys-usage-trend?",i=7;if(w.value==="hour")if(r+="granularity=hour",l.value.customRange&&l.value.customRange.length===2){const n=a=>{const[m,y]=a.split(" "),[C,M,K]=m.split("-").map(Number),[U,F,L]=y.split(":").map(Number);return new Date(Date.UTC(C,M-1,K,U-8,F,L)).toISOString()};r+=`&startDate=${encodeURIComponent(n(l.value.customRange[0]))}`,r+=`&endDate=${encodeURIComponent(n(l.value.customRange[1]))}`}else{const n=new Date;let a,c;if(l.value.type==="preset")switch(l.value.preset){case"last24h":{c=new Date(n),a=new Date(n.getTime()-24*60*60*1e3);break}case"yesterday":{const m=new Date;m.setDate(m.getDate()-1),a=T(m,!0),c=T(m,!1);break}case"dayBefore":{const m=new Date;m.setDate(m.getDate()-2),a=T(m,!0),c=T(m,!1);break}default:a=new Date(n.getTime()-24*60*60*1e3),c=n}else a=new Date(n.getTime()-24*60*60*1e3),c=n;r+=`&startDate=${encodeURIComponent(a.toISOString())}`,r+=`&endDate=${encodeURIComponent(c.toISOString())}`}else i=l.value.type==="preset"?l.value.preset==="today"?1:l.value.preset==="7days"?7:30:Q(l.value.customStart,l.value.customEnd),r+=`granularity=day&days=${i}`;r+=`&metric=${d}`;const u=await J.get(r);u.success&&(I.value={data:u.data||[],topApiKeys:u.topApiKeys||[],totalApiKeys:u.totalApiKeys||0})}catch(r){console.error("加载API Keys趋势失败:",r)}}function V(d){l.value.type="preset",l.value.preset=d;const r=l.value.presetOptions.find(i=>i.value===d);if(r){const i=new Date;let u,n;if(w.value==="hour")switch(d){case"last24h":{n=new Date(i),u=new Date(i.getTime()-24*60*60*1e3);break}case"yesterday":{const a=new Date;a.setDate(a.getDate()-1),u=T(a,!0),n=T(a,!1);break}case"dayBefore":{const a=new Date;a.setDate(a.getDate()-2),u=T(a,!0),n=T(a,!1);break}}else u=new Date(i),n=new Date(i),d==="today"?(u.setHours(0,0,0,0),n.setHours(23,59,59,999)):(u.setDate(i.getDate()-(r.days-1)),u.setHours(0,0,0,0),n.setHours(23,59,59,999));if(l.value.customStart=u.toISOString().split("T")[0],l.value.customEnd=n.toISOString().split("T")[0],w.value==="hour"&&(d==="yesterday"||d==="dayBefore")){const a=new Date;d==="yesterday"?a.setDate(a.getDate()-1):a.setDate(a.getDate()-2);const c=a.getFullYear(),m=String(a.getMonth()+1).padStart(2,"0"),y=String(a.getDate()).padStart(2,"0");l.value.customRange=[`${c}-${m}-${y} 00:00:00`,`${c}-${m}-${y} 23:59:59`]}else{const a=c=>{const C=new Date(c.getTime()+288e5),M=C.getUTCFullYear(),K=String(C.getUTCMonth()+1).padStart(2,"0"),U=String(C.getUTCDate()).padStart(2,"0"),F=String(C.getUTCHours()).padStart(2,"0"),L=String(C.getUTCMinutes()).padStart(2,"0"),Z=String(C.getUTCSeconds()).padStart(2,"0");return`${M}-${K}-${U} ${F}:${L}:${Z}`};l.value.customRange=[a(u),a(n)]}}E()}function ft(d){if(d&&d.length===2){l.value.type="custom",l.value.preset="",l.value.customRange=d,l.value.customStart=d[0].split(" ")[0],l.value.customEnd=d[1].split(" ")[0];const r=n=>{const[a,c]=n.split(" "),[m,y,C]=a.split("-").map(Number),[M,K,U]=c.split(":").map(Number);return new Date(m,y-1,C,M,K,U)},i=r(d[0]),u=r(d[1]);if(w.value==="hour"){if((u-i)/36e5>24){gt("小时粒度下日期范围不能超过24小时","warning");return}}else if(Math.ceil((u-i)/864e5)+1>31){gt("日期范围不能超过 31 天","warning");return}E()}else d===null&&V(w.value==="hour"?"last24h":"7days")}function et(d){if(w.value=d,d==="hour"){if(l.value.presetOptions=[{value:"last24h",label:"近24小时",hours:24},{value:"yesterday",label:"昨天",hours:24},{value:"dayBefore",label:"前天",hours:24}],l.value.type==="custom"&&l.value.customRange&&l.value.customRange.length===2){const r=new Date(l.value.customRange[0]);if((new Date(l.value.customRange[1])-r)/(1e3*60*60)>24){gt("小时粒度下日期范围不能超过24小时已切换到近24小时","warning"),V("last24h");return}}if(["today","7days","30days"].includes(l.value.preset)){V("last24h");return}}else if(l.value.presetOptions=[{value:"today",label:"今日",days:1},{value:"7days",label:"7天",days:7},{value:"30days",label:"30天",days:30}],["last24h","yesterday","dayBefore"].includes(l.value.preset)){V("7days");return}E()}async function E(){let d,r="monthly";if(l.value.type==="preset"){const i=l.value.presetOptions.find(u=>u.value===l.value.preset);w.value==="hour"?(d=1,r="daily"):(d=i?i.days:7,l.value.preset==="today"?r="daily":r="monthly")}else{if(w.value==="hour"){const i=new Date(l.value.customRange[0]),u=new Date(l.value.customRange[1]),n=Math.ceil((u-i)/(1e3*60*60));d=Math.ceil(n/24)||1}else d=Q(l.value.customStart,l.value.customEnd);r="daily"}await Promise.all([rt(d,w.value),it(r),tt(q.value)])}function Q(d,r){if(!d||!r)return 7;const i=new Date(d),u=new Date(r),n=Math.abs(u-i);return Math.ceil(n/(1e3*60*60*24))||7}function j(d){return d>new Date}return{loading:nt,dashboardData:G,costsData:o,modelStats:lt,trendData:H,dashboardModelStats:X,apiKeysTrendData:I,dateFilter:l,trendGranularity:w,apiKeysTrendMetric:q,defaultTime:O,formattedUptime:pt,loadDashboardData:yt,loadUsageTrend:rt,loadModelStats:it,loadApiKeysTrend:tt,setDateFilterPreset:V,onCustomDateRangeChange:ft,setTrendGranularity:et,refreshChartsData:E,disabledDate:j}}),Bt={class:"mb-4 grid grid-cols-1 gap-3 sm:mb-6 sm:grid-cols-2 sm:gap-4 md:mb-8 md:gap-6 lg:grid-cols-4"},Mt={class:"stat-card"},Kt={class:"flex items-center justify-between"},Ot={class:"text-2xl font-bold text-gray-900 sm:text-3xl"},Ft={class:"mt-1 text-xs text-gray-500"},Lt={class:"stat-card"},zt={class:"flex items-center justify-between"},Ht={class:"flex-1"},qt={class:"flex flex-wrap items-baseline gap-x-2"},Et={class:"text-2xl font-bold text-gray-900 sm:text-3xl"},Nt={key:0,class:"flex items-center gap-2"},Vt=["title"],jt={class:"text-xs font-medium text-gray-700"},Yt=["title"],Wt={class:"text-xs font-medium text-gray-700"},Gt=["title"],Qt={class:"text-xs font-medium text-gray-700"},Zt=["title"],Jt={class:"text-xs font-medium text-gray-700"},Xt={class:"mt-1 text-xs text-gray-500"},te={key:0,class:"text-red-600"},ee={key:1,class:"text-gray-600"},se={key:2,class:"text-yellow-600"},ae={class:"stat-card"},oe={class:"flex items-center justify-between"},ne={class:"text-2xl font-bold text-gray-900 sm:text-3xl"},le={class:"mt-1 text-xs text-gray-500"},re={class:"stat-card"},ie={class:"flex items-center justify-between"},de={class:"text-2xl font-bold text-green-600 sm:text-3xl"},ce={class:"mt-1 text-xs text-gray-500"},ue={class:"mb-4 grid grid-cols-1 gap-3 sm:mb-6 sm:grid-cols-2 sm:gap-4 md:mb-8 md:gap-6 lg:grid-cols-4"},me={class:"stat-card"},pe={class:"flex items-center justify-between"},ye={class:"mr-8 flex-1"},fe={class:"mb-2 flex flex-wrap items-baseline gap-2"},xe={class:"text-xl font-bold text-blue-600 sm:text-2xl md:text-3xl"},ge={class:"text-sm font-medium text-green-600"},be={class:"text-xs text-gray-500"},ve={class:"flex flex-wrap items-center justify-between gap-x-4"},he={class:"font-medium"},ke={class:"font-medium"},De={key:0,class:"text-purple-600"},Te={class:"font-medium"},Ce={key:1,class:"text-purple-600"},_e={class:"font-medium"},we={class:"stat-card"},Se={class:"flex items-center justify-between"},Re={class:"mr-8 flex-1"},$e={class:"mb-2 flex flex-wrap items-baseline gap-2"},Ae={class:"text-xl font-bold text-emerald-600 sm:text-2xl md:text-3xl"},Pe={class:"text-sm font-medium text-green-600"},Ie={class:"text-xs text-gray-500"},Ue={class:"flex flex-wrap items-center justify-between gap-x-4"},Be={class:"font-medium"},Me={class:"font-medium"},Ke={key:0,class:"text-purple-600"},Oe={class:"font-medium"},Fe={key:1,class:"text-purple-600"},Le={class:"font-medium"},ze={class:"stat-card"},He={class:"flex items-center justify-between"},qe={class:"mb-1 text-xs font-semibold text-gray-600 sm:text-sm"},Ee={class:"text-xs text-gray-400"},Ne={class:"text-2xl font-bold text-orange-600 sm:text-3xl"},Ve={class:"mt-1 text-xs text-gray-500"},je={key:0,class:"text-yellow-600"},Ye={class:"stat-card"},We={class:"flex items-center justify-between"},Ge={class:"mb-1 text-xs font-semibold text-gray-600 sm:text-sm"},Qe={class:"text-xs text-gray-400"},Ze={class:"text-2xl font-bold text-rose-600 sm:text-3xl"},Je={class:"mt-1 text-xs text-gray-500"},Xe={key:0,class:"text-yellow-600"},ts={class:"mb-8"},es={class:"mb-4 flex flex-col gap-4 sm:mb-6"},ss={class:"flex flex-col gap-2 lg:flex-row lg:items-center lg:justify-end"},as={class:"flex flex-shrink-0 gap-1 overflow-x-auto rounded-lg bg-gray-100 p-1"},os=["onClick"],ns={class:"flex gap-1 rounded-lg bg-gray-100 p-1"},ls={class:"flex items-center gap-2"},rs={key:0,class:"text-xs text-orange-600"},is={class:"flex items-center gap-2"},ds={class:"flex items-center rounded-lg bg-gray-100 px-3 py-1"},cs={class:"relative inline-flex cursor-pointer items-center"},us={class:"ml-2.5 flex select-none items-center gap-1 text-sm font-medium text-gray-600"},ms=["disabled"],ps={class:"hidden sm:inline"},ys={class:"grid grid-cols-1 gap-6 lg:grid-cols-2"},fs={class:"card p-4 sm:p-6"},xs={class:"relative",style:{height:"250px"}},gs={class:"card p-4 sm:p-6"},bs={key:0,class:"py-8 text-center"},vs={key:1,class:"max-h-[250px] overflow-auto sm:max-h-[300px]"},hs={class:"min-w-full"},ks={class:"divide-y divide-gray-200"},Ds={class:"px-2 py-2 text-xs text-gray-900 sm:px-4 sm:text-sm"},Ts=["title"],Cs={class:"hidden px-2 py-2 text-right text-xs text-gray-600 sm:table-cell sm:px-4 sm:text-sm"},_s={class:"px-2 py-2 text-right text-xs text-gray-600 sm:px-4 sm:text-sm"},ws={class:"px-2 py-2 text-right text-xs font-medium text-green-600 sm:px-4 sm:text-sm"},Ss={class:"hidden px-2 py-2 text-right text-xs font-medium sm:table-cell sm:px-4 sm:text-sm"},Rs={class:"inline-flex items-center rounded-full bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800"},$s={class:"mb-4 sm:mb-6 md:mb-8"},As={class:"card p-4 sm:p-6"},Ps={class:"sm:h-[300px]",style:{height:"250px"}},Is={class:"mb-4 sm:mb-6 md:mb-8"},Us={class:"card p-4 sm:p-6"},Bs={class:"mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between"},Ms={class:"flex gap-1 rounded-lg bg-gray-100 p-1"},Ks={class:"mb-4 text-xs text-gray-600 sm:text-sm"},Os={key:0},Fs={key:1},Ls={class:"sm:h-[350px]",style:{height:"300px"}},zs={__name:"DashboardView",setup(nt){const G=Ut(),{dashboardData:o,costsData:lt,dashboardModelStats:H,trendData:X,apiKeysTrendData:I,formattedUptime:l,dateFilter:w,trendGranularity:q,apiKeysTrendMetric:O,defaultTime:pt}=wt(G),{loadDashboardData:T,loadApiKeysTrend:yt,setDateFilterPreset:rt,onCustomDateRangeChange:it,setTrendGranularity:tt,refreshChartsData:V,disabledDate:ft}=G,et=_(null),E=_(null),Q=_(null);let j=null,d=null,r=null;const i=_(!1),u=_(30),n=_(null),a=_(0),c=_(null),m=_(!1);function y(b){return b>=1e6?(b/1e6).toFixed(2)+"M":b>=1e3?(b/1e3).toFixed(2)+"K":b.toString()}function C(b,e){if(!e||e.length===0)return 0;const S=e.reduce((x,N)=>x+N.allTokens,0);return S===0?0:(b/S*100).toFixed(1)}function M(){if(!et.value)return;j&&j.destroy();const b=H.value||[],e={labels:b.map(S=>S.model),datasets:[{data:b.map(S=>S.allTokens),backgroundColor:["#3B82F6","#10B981","#F59E0B","#EF4444","#8B5CF6","#EC4899","#14B8A6","#F97316","#6366F1","#84CC16"],borderWidth:0}]};j=new bt(et.value,{type:"doughnut",data:e,options:{responsive:!0,maintainAspectRatio:!1,plugins:{legend:{position:"bottom",labels:{padding:15,usePointStyle:!0,font:{size:12}}},tooltip:{callbacks:{label:function(S){const x=S.label||"",N=y(S.parsed),st=C(S.parsed,b);return`${x}: ${N} (${st}%)`}}}}}})}function K(){var R;if(!E.value)return;d&&d.destroy();const b=X.value||[],e=b.map(f=>f.inputTokens||0),S=b.map(f=>f.outputTokens||0),x=b.map(f=>f.cacheCreateTokens||0),N=b.map(f=>f.cacheReadTokens||0),st=b.map(f=>f.requests||0),dt=b.map(f=>f.cost||0),ct=(R=b[0])!=null&&R.date?"date":"hour",B={labels:b.map(f=>{if(f.label)return f.label;if(ct==="hour"){const g=new Date(f.hour),A=String(g.getMonth()+1).padStart(2,"0"),Y=String(g.getDate()).padStart(2,"0"),ut=String(g.getHours()).padStart(2,"0");return`${A}/${Y} ${ut}:00`}const D=f.date;if(D&&D.includes("-")){const g=D.split("-");if(g.length>=3)return`${g[1]}/${g[2]}`}return f.date}),datasets:[{label:"输入Token",data:e,borderColor:"rgb(102, 126, 234)",backgroundColor:"rgba(102, 126, 234, 0.1)",tension:.3},{label:"输出Token",data:S,borderColor:"rgb(240, 147, 251)",backgroundColor:"rgba(240, 147, 251, 0.1)",tension:.3},{label:"缓存创建Token",data:x,borderColor:"rgb(59, 130, 246)",backgroundColor:"rgba(59, 130, 246, 0.1)",tension:.3},{label:"缓存读取Token",data:N,borderColor:"rgb(147, 51, 234)",backgroundColor:"rgba(147, 51, 234, 0.1)",tension:.3},{label:"费用 (USD)",data:dt,borderColor:"rgb(34, 197, 94)",backgroundColor:"rgba(34, 197, 94, 0.1)",tension:.3,yAxisID:"y2"},{label:"请求数",data:st,borderColor:"rgb(16, 185, 129)",backgroundColor:"rgba(16, 185, 129, 0.1)",tension:.3,yAxisID:"y1"}]};d=new bt(E.value,{type:"line",data:B,options:{responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},plugins:{title:{display:!0,text:"Token使用趋势",font:{size:16,weight:"bold"}},legend:{position:"top"},tooltip:{mode:"index",intersect:!1,itemSort:function(f,D){const g=f.dataset.label||"",A=D.dataset.label||"";return g==="费用 (USD)"||A==="费用 (USD)"?g==="费用 (USD)"?-1:1:g==="请求数"||A==="请求数"?g==="请求数"?1:-1:D.parsed.y-f.parsed.y},callbacks:{label:function(f){const D=f.dataset.label||"";let g=f.parsed.y;return D==="费用 (USD)"?g<.01?D+": $"+g.toFixed(6):D+": $"+g.toFixed(4):D==="请求数"?D+": "+g.toLocaleString()+" 次":g>=1e6?D+": "+(g/1e6).toFixed(2)+"M tokens":g>=1e3?D+": "+(g/1e3).toFixed(2)+"K tokens":D+": "+g.toLocaleString()+" tokens"}}}},scales:{x:{type:"category",display:!0,title:{display:!0,text:q.value==="hour"?"时间":"日期"}},y:{type:"linear",display:!0,position:"left",title:{display:!0,text:"Token数量"},ticks:{callback:function(f){return y(f)}}},y1:{type:"linear",display:!0,position:"right",title:{display:!0,text:"请求数"},grid:{drawOnChartArea:!1},ticks:{callback:function(f){return f.toLocaleString()}}},y2:{type:"linear",display:!1,position:"right"}}}})}function U(){var dt,ct;if(!Q.value)return;r&&r.destroy();const b=I.value.data||[],e=O.value,S=["#3B82F6","#10B981","#F59E0B","#EF4444","#8B5CF6","#EC4899","#14B8A6","#F97316","#6366F1","#84CC16"],x=((dt=I.value.topApiKeys)==null?void 0:dt.map((k,B)=>{var D,g;const R=I.value.data.map(A=>!A.apiKeys||!A.apiKeys[k]?0:e==="tokens"?A.apiKeys[k].tokens:A.apiKeys[k].requests||0);return{label:((g=(D=I.value.data.find(A=>A.apiKeys&&A.apiKeys[k]))==null?void 0:D.apiKeys[k])==null?void 0:g.name)||`API Key ${k}`,data:R,borderColor:S[B%S.length],backgroundColor:S[B%S.length]+"20",tension:.4,fill:!1}}))||[],N=(ct=b[0])!=null&&ct.date?"date":"hour",st={labels:b.map(k=>{if(k.label)return k.label;if(N==="hour"){const R=new Date(k.hour),f=String(R.getMonth()+1).padStart(2,"0"),D=String(R.getDate()).padStart(2,"0"),g=String(R.getHours()).padStart(2,"0");return`${f}/${D} ${g}:00`}const B=k.date;if(B&&B.includes("-")){const R=B.split("-");if(R.length>=3)return`${R[1]}/${R[2]}`}return k.date}),datasets:x};r=new bt(Q.value,{type:"line",data:st,options:{responsive:!0,maintainAspectRatio:!1,plugins:{legend:{position:"bottom",labels:{padding:20,usePointStyle:!0,font:{size:12}}},tooltip:{mode:"index",intersect:!1,itemSort:function(k,B){return B.parsed.y-k.parsed.y},callbacks:{label:function(k){var ut;const B=k.dataset.label||"",R=k.parsed.y,f=k.dataIndex,D=I.value.data[f],A=k.chart.data.datasets.map((z,at)=>({value:z.data[f]||0,index:at})).sort((z,at)=>at.value-z.value).findIndex(z=>z.index===k.datasetIndex)+1;let Y="";if(A===1?Y="🥇 ":A===2?Y="🥈 ":A===3&&(Y="🥉 "),O.value==="tokens"){let z="";R>=1e6?z=(R/1e6).toFixed(2)+"M":R>=1e3?z=(R/1e3).toFixed(2)+"K":z=R.toLocaleString();const at=I.value.topApiKeys[k.datasetIndex],xt=(ut=D==null?void 0:D.apiKeys)==null?void 0:ut[at],Dt=(xt==null?void 0:xt.formattedCost)||"$0.00";return`${Y}${B}: ${z} tokens (${Dt})`}else return`${Y}${B}: ${R.toLocaleString()}`}}}},scales:{x:{type:"category",display:!0,title:{display:!0,text:q.value==="hour"?"时间":"日期"}},y:{beginAtZero:!0,title:{display:!0,text:O.value==="tokens"?"Token 数量":"请求次数"},ticks:{callback:function(k){return y(k)}}}}}})}async function F(){await yt(O.value),await ot(),U()}mt(H,()=>{ot(()=>M())}),mt(X,()=>{ot(()=>K())}),mt(I,()=>{ot(()=>U())});async function L(){if(!m.value){m.value=!0;try{await Promise.all([T(),V()])}finally{m.value=!1}}}function Z(){i.value&&(a.value=u.value,c.value&&clearInterval(c.value),n.value&&clearTimeout(n.value),c.value=setInterval(()=>{a.value--,a.value<=0&&clearInterval(c.value)},1e3),n.value=setTimeout(async()=>{await L(),i.value&&Z()},u.value*1e3))}function vt(){c.value&&(clearInterval(c.value),c.value=null),n.value&&(clearTimeout(n.value),n.value=null),a.value=0}return mt(i,b=>{b?Z():vt()}),St(async()=>{await L(),await ot(),M(),K(),U()}),Rt(()=>{vt(),j&&j.destroy(),d&&d.destroy(),r&&r.destroy()}),(b,e)=>{const S=Tt;return h(),v("div",null,[t("div",Bt,[t("div",Mt,[t("div",Kt,[t("div",null,[e[7]||(e[7]=t("p",{class:"mb-1 text-xs font-semibold text-gray-600 sm:text-sm"},"总API Keys",-1)),t("p",Ot,p(s(o).totalApiKeys),1),t("p",Ft,"活跃: "+p(s(o).activeApiKeys||0),1)]),e[8]||(e[8]=t("div",{class:"stat-icon flex-shrink-0 bg-gradient-to-br from-blue-500 to-blue-600"},[t("i",{class:"fas fa-key"})],-1))])]),t("div",Lt,[t("div",zt,[t("div",Ht,[e[13]||(e[13]=t("p",{class:"mb-1 text-xs font-semibold text-gray-600 sm:text-sm"},"服务账户",-1)),t("div",qt,[t("p",Et,p(s(o).totalAccounts),1),s(o).accountsByPlatform?(h(),v("div",Nt,[s(o).accountsByPlatform.claude&&s(o).accountsByPlatform.claude.total>0?(h(),v("div",{key:0,class:"inline-flex items-center gap-0.5",title:`Claude: ${s(o).accountsByPlatform.claude.total} 个 (正常: ${s(o).accountsByPlatform.claude.normal})`},[e[9]||(e[9]=t("i",{class:"fas fa-brain text-xs text-indigo-600"},null,-1)),t("span",jt,p(s(o).accountsByPlatform.claude.total),1)],8,Vt)):P("",!0),s(o).accountsByPlatform["claude-console"]&&s(o).accountsByPlatform["claude-console"].total>0?(h(),v("div",{key:1,class:"inline-flex items-center gap-0.5",title:`Console: ${s(o).accountsByPlatform["claude-console"].total} 个 (正常: ${s(o).accountsByPlatform["claude-console"].normal})`},[e[10]||(e[10]=t("i",{class:"fas fa-terminal text-xs text-purple-600"},null,-1)),t("span",Wt,p(s(o).accountsByPlatform["claude-console"].total),1)],8,Yt)):P("",!0),s(o).accountsByPlatform.gemini&&s(o).accountsByPlatform.gemini.total>0?(h(),v("div",{key:2,class:"inline-flex items-center gap-0.5",title:`Gemini: ${s(o).accountsByPlatform.gemini.total} 个 (正常: ${s(o).accountsByPlatform.gemini.normal})`},[e[11]||(e[11]=t("i",{class:"fas fa-robot text-xs text-yellow-600"},null,-1)),t("span",Qt,p(s(o).accountsByPlatform.gemini.total),1)],8,Gt)):P("",!0),s(o).accountsByPlatform.bedrock&&s(o).accountsByPlatform.bedrock.total>0?(h(),v("div",{key:3,class:"inline-flex items-center gap-0.5",title:`Bedrock: ${s(o).accountsByPlatform.bedrock.total} 个 (正常: ${s(o).accountsByPlatform.bedrock.normal})`},[e[12]||(e[12]=t("i",{class:"fab fa-aws text-xs text-orange-600"},null,-1)),t("span",Jt,p(s(o).accountsByPlatform.bedrock.total),1)],8,Zt)):P("",!0)])):P("",!0)]),t("p",Xt,[$(" 正常: "+p(s(o).normalAccounts||0)+" ",1),s(o).abnormalAccounts>0?(h(),v("span",te," | 异常: "+p(s(o).abnormalAccounts),1)):P("",!0),s(o).pausedAccounts>0?(h(),v("span",ee," | 停止调度: "+p(s(o).pausedAccounts),1)):P("",!0),s(o).rateLimitedAccounts>0?(h(),v("span",se," | 限流: "+p(s(o).rateLimitedAccounts),1)):P("",!0)])]),e[14]||(e[14]=t("div",{class:"stat-icon ml-2 flex-shrink-0 bg-gradient-to-br from-green-500 to-green-600"},[t("i",{class:"fas fa-user-circle"})],-1))])]),t("div",ae,[t("div",oe,[t("div",null,[e[15]||(e[15]=t("p",{class:"mb-1 text-xs font-semibold text-gray-600 sm:text-sm"},"今日请求",-1)),t("p",ne,p(s(o).todayRequests),1),t("p",le," 总请求: "+p(y(s(o).totalRequests||0)),1)]),e[16]||(e[16]=t("div",{class:"stat-icon flex-shrink-0 bg-gradient-to-br from-purple-500 to-purple-600"},[t("i",{class:"fas fa-chart-line"})],-1))])]),t("div",re,[t("div",ie,[t("div",null,[e[17]||(e[17]=t("p",{class:"mb-1 text-xs font-semibold text-gray-600 sm:text-sm"},"系统状态",-1)),t("p",de,p(s(o).systemStatus),1),t("p",ce,"运行时间: "+p(s(l)),1)]),e[18]||(e[18]=t("div",{class:"stat-icon flex-shrink-0 bg-gradient-to-br from-yellow-500 to-orange-500"},[t("i",{class:"fas fa-heartbeat"})],-1))])])]),t("div",ue,[t("div",me,[t("div",pe,[t("div",ye,[e[23]||(e[23]=t("p",{class:"mb-1 text-xs font-semibold text-gray-600 sm:text-sm"},"今日Token",-1)),t("div",fe,[t("p",xe,p(y((s(o).todayInputTokens||0)+(s(o).todayOutputTokens||0)+(s(o).todayCacheCreateTokens||0)+(s(o).todayCacheReadTokens||0))),1),t("span",ge,"/ "+p(s(lt).todayCosts.formatted.totalCost),1)]),t("div",be,[t("div",ve,[t("span",null,[e[19]||(e[19]=$("输入: ",-1)),t("span",he,p(y(s(o).todayInputTokens||0)),1)]),t("span",null,[e[20]||(e[20]=$("输出: ",-1)),t("span",ke,p(y(s(o).todayOutputTokens||0)),1)]),(s(o).todayCacheCreateTokens||0)>0?(h(),v("span",De,[e[21]||(e[21]=$("缓存创建: ",-1)),t("span",Te,p(y(s(o).todayCacheCreateTokens||0)),1)])):P("",!0),(s(o).todayCacheReadTokens||0)>0?(h(),v("span",Ce,[e[22]||(e[22]=$("缓存读取: ",-1)),t("span",_e,p(y(s(o).todayCacheReadTokens||0)),1)])):P("",!0)])])]),e[24]||(e[24]=t("div",{class:"stat-icon flex-shrink-0 bg-gradient-to-br from-indigo-500 to-indigo-600"},[t("i",{class:"fas fa-coins"})],-1))])]),t("div",we,[t("div",Se,[t("div",Re,[e[29]||(e[29]=t("p",{class:"mb-1 text-xs font-semibold text-gray-600 sm:text-sm"},"总Token消耗",-1)),t("div",$e,[t("p",Ae,p(y((s(o).totalInputTokens||0)+(s(o).totalOutputTokens||0)+(s(o).totalCacheCreateTokens||0)+(s(o).totalCacheReadTokens||0))),1),t("span",Pe,"/ "+p(s(lt).totalCosts.formatted.totalCost),1)]),t("div",Ie,[t("div",Ue,[t("span",null,[e[25]||(e[25]=$("输入: ",-1)),t("span",Be,p(y(s(o).totalInputTokens||0)),1)]),t("span",null,[e[26]||(e[26]=$("输出: ",-1)),t("span",Me,p(y(s(o).totalOutputTokens||0)),1)]),(s(o).totalCacheCreateTokens||0)>0?(h(),v("span",Ke,[e[27]||(e[27]=$("缓存创建: ",-1)),t("span",Oe,p(y(s(o).totalCacheCreateTokens||0)),1)])):P("",!0),(s(o).totalCacheReadTokens||0)>0?(h(),v("span",Fe,[e[28]||(e[28]=$("缓存读取: ",-1)),t("span",Le,p(y(s(o).totalCacheReadTokens||0)),1)])):P("",!0)])])]),e[30]||(e[30]=t("div",{class:"stat-icon flex-shrink-0 bg-gradient-to-br from-emerald-500 to-emerald-600"},[t("i",{class:"fas fa-database"})],-1))])]),t("div",ze,[t("div",He,[t("div",null,[t("p",qe,[e[31]||(e[31]=$(" 实时RPM ",-1)),t("span",Ee,"("+p(s(o).metricsWindow)+"分钟)",1)]),t("p",Ne,p(s(o).realtimeRPM||0),1),t("p",Ve,[e[33]||(e[33]=$(" 每分钟请求数 ",-1)),s(o).isHistoricalMetrics?(h(),v("span",je,e[32]||(e[32]=[t("i",{class:"fas fa-exclamation-circle"},null,-1),$(" 历史数据 ",-1)]))):P("",!0)])]),e[34]||(e[34]=t("div",{class:"stat-icon flex-shrink-0 bg-gradient-to-br from-orange-500 to-orange-600"},[t("i",{class:"fas fa-tachometer-alt"})],-1))])]),t("div",Ye,[t("div",We,[t("div",null,[t("p",Ge,[e[35]||(e[35]=$(" 实时TPM ",-1)),t("span",Qe,"("+p(s(o).metricsWindow)+"分钟)",1)]),t("p",Ze,p(y(s(o).realtimeTPM||0)),1),t("p",Je,[e[37]||(e[37]=$(" 每分钟Token数 ",-1)),s(o).isHistoricalMetrics?(h(),v("span",Xe,e[36]||(e[36]=[t("i",{class:"fas fa-exclamation-circle"},null,-1),$(" 历史数据 ",-1)]))):P("",!0)])]),e[38]||(e[38]=t("div",{class:"stat-icon flex-shrink-0 bg-gradient-to-br from-rose-500 to-rose-600"},[t("i",{class:"fas fa-rocket"})],-1))])])]),t("div",ts,[t("div",es,[e[45]||(e[45]=t("h3",{class:"text-lg font-bold text-gray-900 sm:text-xl"},"模型使用分布与Token使用趋势",-1)),t("div",ss,[t("div",as,[(h(!0),v(ht,null,kt(s(w).presetOptions,x=>(h(),v("button",{key:x.value,class:W(["rounded-md px-3 py-1 text-sm font-medium transition-colors",s(w).preset===x.value&&s(w).type==="preset"?"bg-white text-blue-600 shadow-sm":"text-gray-600 hover:text-gray-900"]),onClick:N=>s(rt)(x.value)},p(x.label),11,os))),128))]),t("div",ns,[t("button",{class:W(["rounded-md px-3 py-1 text-sm font-medium transition-colors",s(q)==="day"?"bg-white text-blue-600 shadow-sm":"text-gray-600 hover:text-gray-900"]),onClick:e[0]||(e[0]=x=>s(tt)("day"))},e[39]||(e[39]=[t("i",{class:"fas fa-calendar-day mr-1"},null,-1),$("按天 ",-1)]),2),t("button",{class:W(["rounded-md px-3 py-1 text-sm font-medium transition-colors",s(q)==="hour"?"bg-white text-blue-600 shadow-sm":"text-gray-600 hover:text-gray-900"]),onClick:e[1]||(e[1]=x=>s(tt)("hour"))},e[40]||(e[40]=[t("i",{class:"fas fa-clock mr-1"},null,-1),$("按小时 ",-1)]),2)]),t("div",ls,[$t(S,{modelValue:s(w).customRange,"onUpdate:modelValue":e[2]||(e[2]=x=>s(w).customRange=x),class:"custom-date-picker w-full lg:w-auto","default-time":s(pt),"disabled-date":s(ft),"end-placeholder":"结束日期",format:"YYYY-MM-DD HH:mm:ss","range-separator":"至",size:"default","start-placeholder":"开始日期",style:{"max-width":"400px"},type:"datetimerange","value-format":"YYYY-MM-DD HH:mm:ss",onChange:s(it)},null,8,["modelValue","default-time","disabled-date","onChange"]),s(q)==="hour"?(h(),v("span",rs,e[41]||(e[41]=[t("i",{class:"fas fa-info-circle"},null,-1),$(" 最多24小时 ",-1)]))):P("",!0)]),t("div",is,[t("div",ds,[t("label",cs,[At(t("input",{"onUpdate:modelValue":e[3]||(e[3]=x=>i.value=x),class:"peer sr-only",type:"checkbox"},null,512),[[Pt,i.value]]),e[44]||(e[44]=t("div",{class:"peer relative h-5 w-9 rounded-full bg-gray-300 transition-all duration-200 after:absolute after:left-[2px] after:top-0.5 after:h-4 after:w-4 after:rounded-full after:bg-white after:shadow-sm after:transition-transform after:duration-200 after:content-[''] peer-checked:bg-blue-500 peer-checked:after:translate-x-4 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-300"},null,-1)),t("span",us,[e[42]||(e[42]=t("i",{class:"fas fa-redo-alt text-xs text-gray-500"},null,-1)),e[43]||(e[43]=t("span",null,"自动刷新",-1)),i.value?(h(),v("span",{key:0,class:W(["ml-1 font-mono text-xs text-blue-600 transition-opacity",a.value>0?"opacity-100":"opacity-0"])},p(a.value)+"s ",3)):P("",!0)])])]),t("button",{class:"flex items-center gap-1 rounded-md border border-gray-300 bg-white px-3 py-1 text-sm font-medium text-blue-600 shadow-sm transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 sm:gap-2",disabled:m.value,title:"立即刷新数据",onClick:e[4]||(e[4]=x=>L())},[t("i",{class:W(["fas fa-sync-alt text-xs",{"animate-spin":m.value}])},null,2),t("span",ps,p(m.value?"刷新中":"刷新"),1)],8,ms)])])]),t("div",ys,[t("div",fs,[e[46]||(e[46]=t("h4",{class:"mb-4 text-base font-semibold text-gray-800 sm:text-lg"},"Token使用分布",-1)),t("div",xs,[t("canvas",{ref_key:"modelUsageChart",ref:et},null,512)])]),t("div",gs,[e[49]||(e[49]=t("h4",{class:"mb-4 text-base font-semibold text-gray-800 sm:text-lg"},"详细统计数据",-1)),s(H).length===0?(h(),v("div",bs,e[47]||(e[47]=[t("p",{class:"text-sm text-gray-500 sm:text-base"},"暂无模型使用数据",-1)]))):(h(),v("div",vs,[t("table",hs,[e[48]||(e[48]=t("thead",{class:"sticky top-0 bg-gray-50"},[t("tr",null,[t("th",{class:"px-2 py-2 text-left text-xs font-medium text-gray-700 sm:px-4"}," 模型 "),t("th",{class:"hidden px-2 py-2 text-right text-xs font-medium text-gray-700 sm:table-cell sm:px-4"}," 请求数 "),t("th",{class:"px-2 py-2 text-right text-xs font-medium text-gray-700 sm:px-4"}," 总Token "),t("th",{class:"px-2 py-2 text-right text-xs font-medium text-gray-700 sm:px-4"}," 费用 "),t("th",{class:"hidden px-2 py-2 text-right text-xs font-medium text-gray-700 sm:table-cell sm:px-4"}," 占比 ")])],-1)),t("tbody",ks,[(h(!0),v(ht,null,kt(s(H),x=>(h(),v("tr",{key:x.model,class:"hover:bg-gray-50"},[t("td",Ds,[t("span",{class:"block max-w-[100px] truncate sm:max-w-none",title:x.model},p(x.model),9,Ts)]),t("td",Cs,p(y(x.requests)),1),t("td",_s,p(y(x.allTokens)),1),t("td",ws,p(x.formatted?x.formatted.total:"$0.000000"),1),t("td",Ss,[t("span",Rs,p(C(x.allTokens,s(H)))+"% ",1)])]))),128))])])]))])])]),t("div",$s,[t("div",As,[t("div",Ps,[t("canvas",{ref_key:"usageTrendChart",ref:E},null,512)])])]),t("div",Is,[t("div",Us,[t("div",Bs,[e[52]||(e[52]=t("h3",{class:"text-base font-semibold text-gray-900 sm:text-lg"},"API Keys 使用趋势",-1)),t("div",Ms,[t("button",{class:W(["rounded-md px-2 py-1 text-xs font-medium transition-colors sm:px-3 sm:text-sm",s(O)==="requests"?"bg-white text-blue-600 shadow-sm":"text-gray-600 hover:text-gray-900"]),onClick:e[5]||(e[5]=x=>(O.value="requests",F()))},e[50]||(e[50]=[t("i",{class:"fas fa-exchange-alt mr-1"},null,-1),t("span",{class:"hidden sm:inline"},"请求次数",-1),t("span",{class:"sm:hidden"},"请求",-1)]),2),t("button",{class:W(["rounded-md px-2 py-1 text-xs font-medium transition-colors sm:px-3 sm:text-sm",s(O)==="tokens"?"bg-white text-blue-600 shadow-sm":"text-gray-600 hover:text-gray-900"]),onClick:e[6]||(e[6]=x=>(O.value="tokens",F()))},e[51]||(e[51]=[t("i",{class:"fas fa-coins mr-1"},null,-1),t("span",{class:"hidden sm:inline"},"Token 数量",-1),t("span",{class:"sm:hidden"},"Token",-1)]),2)])]),t("div",Ks,[s(I).totalApiKeys>10?(h(),v("span",Os," 共 "+p(s(I).totalApiKeys)+" 个 API Key显示使用量前 10 个 ",1)):(h(),v("span",Fs," 共 "+p(s(I).totalApiKeys)+" 个 API Key ",1))]),t("div",Ls,[t("canvas",{ref_key:"apiKeysUsageTrendChart",ref:Q},null,512)])])])])}}},Ys=It(zs,[["__scopeId","data-v-36eb09ef"]]);export{Ys as default};