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