mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 00:53:33 +00:00
2 lines
35 KiB
JavaScript
2 lines
35 KiB
JavaScript
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-BMhthBXv.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};
|