Files
claude-relay-service/assets/ApiStatsView-CPGIbNYc.js
2025-09-07 05:36:55 +00:00

6 lines
45 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{aP as xt,r as C,c as E,aX as N,x as n,y as l,z as t,O as f,L as K,P as r,u as e,C as D,K as tt,aq as et,aa as st,f as at,Y as gt,Q as J,ac as z,B as it,R as U,q as yt,aW as ft,V as pt,o as bt,I as Q,J as rt,av as vt}from"./vue-vendor-Bsazo-x0.js";import{_ as O,a as kt}from"./index-QmGprD3N.js";import{L as _t}from"./LogoTitle-YpzR_qDl.js";import{T as ht}from"./ThemeToggle-BxFO_8Mf.js";import{b as wt}from"./vendor-C8JtMHuO.js";import{_ as $t}from"./WindowCountdown-BTXjZ8Dc.js";import St from"./TutorialView-kheW7AWN.js";import"./element-plus-C5sO7D8l.js";class Kt{constructor(){this.baseURL=window.location.origin,this.isDev=!1}async request(u,a={}){try{this.isDev&&u.startsWith("/admin")&&(u="/webapi"+u);const c=await fetch(`${this.baseURL}${u}`,{headers:{"Content-Type":"application/json",...a.headers},...a}),m=await c.json();if(!c.ok)throw new Error(m.message||`请求失败: ${c.status}`);return m}catch(c){throw console.error("API Stats request error:",c),c}}async getKeyId(u){return this.request("/apiStats/api/get-key-id",{method:"POST",body:JSON.stringify({apiKey:u})})}async getUserStats(u){return this.request("/apiStats/api/user-stats",{method:"POST",body:JSON.stringify({apiId:u})})}async getUserModelStats(u,a="daily"){return this.request("/apiStats/api/user-model-stats",{method:"POST",body:JSON.stringify({apiId:u,period:a})})}async getOemSettings(){try{return await this.request("/admin/oem-settings")}catch(u){return console.error("Failed to load OEM settings:",u),{success:!0,data:{siteName:"Claude Relay Service",siteIcon:"",siteIconData:""}}}}async getBatchStats(u){return this.request("/apiStats/api/batch-stats",{method:"POST",body:JSON.stringify({apiIds:u})})}async getBatchModelStats(u,a="daily"){return this.request("/apiStats/api/batch-model-stats",{method:"POST",body:JSON.stringify({apiIds:u,period:a})})}}const R=new Kt,B=xt("apistats",()=>{const P=C(""),u=C(null),a=C(!1),c=C(!1),m=C(!0),x=C(""),d=C("daily"),y=C(null),b=C([]),v=C(null),s=C(null),p=C({siteName:"",siteIcon:"",siteIconData:""}),A=C(!1),w=C([]),$=C([]),k=C(null),S=C([]),g=C([]),o=E(()=>{const i={requests:0,inputTokens:0,outputTokens:0,cacheCreateTokens:0,cacheReadTokens:0,allTokens:0,cost:0,formattedCost:"$0.000000"};return A.value&&k.value?d.value==="daily"?k.value.dailyUsage||i:k.value.monthlyUsage||i:d.value==="daily"?v.value||i:s.value||i}),I=E(()=>{if(!y.value||!o.value)return{tokenUsage:0,costUsage:0,requestUsage:0};const i=o.value,h=y.value.limits;return{tokenUsage:h.tokenLimit>0?Math.min(i.allTokens/h.tokenLimit*100,100):0,costUsage:h.dailyCostLimit>0?Math.min(i.cost/h.dailyCostLimit*100,100):0,requestUsage:h.rateLimitRequests>0?Math.min(i.requests/h.rateLimitRequests*100,100):0}});async function q(){if(A.value)return G();if(!P.value.trim()){x.value="请输入 API Key";return}a.value=!0,x.value="",y.value=null,b.value=[],u.value=null;try{const i=await R.getKeyId(P.value);if(i.success){u.value=i.data.id;const h=await R.getUserStats(u.value);if(h.success)y.value=h.data,await V(),x.value="",ot();else throw new Error(h.message||"查询失败")}else throw new Error(i.message||"获取 API Key ID 失败")}catch(i){console.error("Query stats error:",i),x.value=i.message||"查询统计数据失败,请检查您的 API Key 是否正确",y.value=null,b.value=[],u.value=null}finally{a.value=!1}}async function V(){u.value&&(await Promise.all([T("daily"),T("monthly")]),await _(d.value))}async function T(i){try{const h=await R.getUserModelStats(u.value,i);if(h.success){const j=h.data||[],M={requests:0,inputTokens:0,outputTokens:0,cacheCreateTokens:0,cacheReadTokens:0,allTokens:0,cost:0,formattedCost:"$0.000000"};j.forEach(L=>{var F;M.requests+=L.requests||0,M.inputTokens+=L.inputTokens||0,M.outputTokens+=L.outputTokens||0,M.cacheCreateTokens+=L.cacheCreateTokens||0,M.cacheReadTokens+=L.cacheReadTokens||0,M.allTokens+=L.allTokens||0,M.cost+=((F=L.costs)==null?void 0:F.total)||0}),M.formattedCost=nt(M.cost),i==="daily"?v.value=M:s.value=M}else console.warn(`Failed to load ${i} stats:`,h.message)}catch(h){console.error(`Load ${i} stats error:`,h)}}async function _(i="daily"){if(u.value){c.value=!0;try{const h=await R.getUserModelStats(u.value,i);if(h.success)b.value=h.data||[];else throw new Error(h.message||"加载模型统计失败")}catch(h){console.error("Load model stats error:",h),b.value=[]}finally{c.value=!1}}}async function Y(i){if(!(d.value===i||c.value)){if(d.value=i,A.value&&$.value.length>0){await H(i);return}(i==="daily"&&!v.value||i==="monthly"&&!s.value)&&await T(i),await _(i)}}async function W(){if(u.value){a.value=!0,x.value="",y.value=null,b.value=[];try{const i=await R.getUserStats(u.value);if(i.success)y.value=i.data,await V(),x.value="";else throw new Error(i.message||"查询失败")}catch(i){console.error("Load stats with apiId error:",i),x.value=i.message||"查询统计数据失败",y.value=null,b.value=[]}finally{a.value=!1}}}async function lt(){m.value=!0;try{const i=await R.getOemSettings();i&&i.success&&i.data&&(p.value={...p.value,...i.data})}catch(i){console.error("Error loading OEM settings:",i),p.value={siteName:"Claude Relay Service",siteIcon:"",siteIconData:""}}finally{m.value=!1}}function nt(i){return typeof i!="number"||i===0?"$0.000000":i>=1?"$"+i.toFixed(2):i>=.01?"$"+i.toFixed(4):"$"+i.toFixed(6)}function ot(){if(u.value){const i=new URL(window.location);i.searchParams.set("apiId",u.value),window.history.pushState({},"",i)}}async function G(){const i=dt();if(i.length===0){x.value="请输入至少一个有效的 API Key";return}a.value=!0,x.value="",k.value=null,S.value=[],g.value=[],b.value=[],w.value=i,$.value=[];try{const h=await Promise.allSettled(i.map(F=>R.getKeyId(F))),j=[],M=[];if(h.forEach((F,Z)=>{F.status==="fulfilled"&&F.value.success?(j.push(F.value.data.id),M.push(i[Z])):g.value.push(i[Z])}),j.length===0)throw new Error("所有 API Key 都无效");$.value=j,w.value=M;const L=await R.getBatchStats(j);if(L.success)k.value=L.data.aggregated,S.value=L.data.individual,y.value=L.data.aggregated,v.value=L.data.aggregated.dailyUsage||null,s.value=L.data.aggregated.monthlyUsage||null,await H(d.value),mt();else throw new Error(L.message||"批量查询失败")}catch(h){console.error("Batch query error:",h),x.value=h.message||"批量查询统计数据失败",k.value=null,S.value=[]}finally{a.value=!1}}async function H(i="daily"){if($.value.length!==0){c.value=!0;try{const h=await R.getBatchModelStats($.value,i);if(h.success)b.value=h.data||[];else throw new Error(h.message||"加载批量模型统计失败")}catch(h){console.error("Load batch model stats error:",h),b.value=[]}finally{c.value=!1}}}function dt(){if(!P.value)return[];const i=P.value.split(/[,\n]+/).map(j=>j.trim()).filter(j=>j.length>0);return[...new Set(i)].slice(0,30)}function mt(){if($.value.length>0){const i=new URL(window.location);i.searchParams.set("apiIds",$.value.join(",")),i.searchParams.set("batch","true"),window.history.pushState({},"",i)}}function ct(){P.value=""}function X(){y.value=null,b.value=[],v.value=null,s.value=null,x.value="",d.value="daily",u.value=null,w.value=[],$.value=[],k.value=null,S.value=[],g.value=[]}function ut(){P.value="",A.value=!1,X()}return{apiKey:P,apiId:u,loading:a,modelStatsLoading:c,oemLoading:m,error:x,statsPeriod:d,statsData:y,modelStats:b,dailyStats:v,monthlyStats:s,oemSettings:p,multiKeyMode:A,apiKeys:w,apiIds:$,aggregatedStats:k,individualStats:S,invalidKeys:g,currentPeriodData:o,usagePercentages:I,queryStats:q,queryBatchStats:G,loadAllPeriodStats:V,loadPeriodStats:T,loadModelStats:_,loadBatchModelStats:H,switchPeriod:Y,loadStatsWithApiId:W,loadOemSettings:lt,clearData:X,clearInput:ct,reset:ut}}),Ct={class:"api-input-wide-card mb-8 rounded-3xl p-6 shadow-xl"},Tt={class:"mx-auto max-w-4xl"},It={class:"control-bar mb-4 flex flex-wrap items-center justify-between gap-3"},Pt={class:"text-sm font-medium text-gray-700 dark:text-gray-300"},Lt={class:"button-group flex items-center gap-2"},Mt={class:"mode-switch-group flex items-center rounded-lg bg-gray-100 p-1 dark:bg-gray-800"},At={key:0,class:"ml-1 rounded-full bg-white/20 px-1.5 py-0.5 text-xs font-semibold"},qt={class:"api-input-grid grid grid-cols-1 gap-4 lg:grid-cols-4"},Dt={class:"lg:col-span-3"},jt=["disabled"],Rt={key:1,class:"relative"},Ut=["disabled"],Et={class:"lg:col-span-1"},Ft=["disabled"],Nt={key:0,class:"fas fa-spinner loading-spinner"},Ot={key:1,class:"fas fa-search"},Bt={class:"security-notice mt-4"},Vt={key:0,class:"mt-2 rounded-lg bg-blue-50 p-3 text-sm text-blue-700 dark:bg-blue-900/20 dark:text-blue-400"},Wt={__name:"ApiKeyInput",setup(P){const u=B(),{apiKey:a,loading:c,multiKeyMode:m}=N(u),{queryStats:x,clearInput:d}=u,y=E(()=>{if(!m.value||!a.value)return[];const v=a.value.split(/[,\n]+/).map(p=>p.trim()).filter(p=>p.length>0);return[...new Set(v)].slice(0,30)}),b=E(()=>m.value?y.value.length>0:a.value&&a.value.trim().length>0);return(v,s)=>(l(),n("div",Ct,[s[15]||(s[15]=t("div",{class:"wide-card-title mb-6"},[t("h2",{class:"mb-2 text-2xl font-bold text-gray-900 dark:text-gray-200"},[t("i",{class:"fas fa-chart-line mr-3"}),f(" 使用统计查询 ")]),t("p",{class:"text-base text-gray-600 dark:text-gray-400"},"查询您的 API Key 使用情况和统计数据")],-1)),t("div",Tt,[t("div",It,[t("label",Pt,[s[8]||(s[8]=t("i",{class:"fas fa-key mr-2"},null,-1)),f(" "+r(e(m)?"输入您的 API Keys每行一个或用逗号分隔":"输入您的 API Key"),1)]),t("div",Lt,[t("div",Mt,[t("button",{class:D(["mode-switch-btn",{active:!e(m)}]),title:"单一模式",onClick:s[0]||(s[0]=p=>m.value=!1)},s[9]||(s[9]=[t("i",{class:"fas fa-key"},null,-1),t("span",{class:"ml-2 hidden sm:inline"},"单一",-1)]),2),t("button",{class:D(["mode-switch-btn",{active:e(m)}]),title:"聚合模式",onClick:s[1]||(s[1]=p=>m.value=!0)},[s[10]||(s[10]=t("i",{class:"fas fa-layer-group"},null,-1)),s[11]||(s[11]=t("span",{class:"ml-2 hidden sm:inline"},"聚合",-1)),e(m)&&y.value.length>0?(l(),n("span",At,r(y.value.length),1)):K("",!0)],2)])])]),t("div",qt,[t("div",Dt,[e(m)?(l(),n("div",Rt,[tt(t("textarea",{"onUpdate:modelValue":s[4]||(s[4]=p=>at(a)?a.value=p:null),class:"wide-card-input w-full resize-y",disabled:e(c),placeholder:`请输入您的 API Keys支持以下格式
cr_xxx
cr_yyy
cr_xxx, cr_yyy`,rows:"4",onKeyup:s[5]||(s[5]=st(gt((...p)=>e(x)&&e(x)(...p),["ctrl"]),["enter"]))},null,40,Ut),[[et,e(a)]]),e(a)&&!e(c)?(l(),n("button",{key:0,class:"absolute right-2 top-2 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300",title:"清空输入",onClick:s[6]||(s[6]=(...p)=>e(d)&&e(d)(...p))},s[12]||(s[12]=[t("i",{class:"fas fa-times-circle"},null,-1)]))):K("",!0)])):tt((l(),n("input",{key:0,"onUpdate:modelValue":s[2]||(s[2]=p=>at(a)?a.value=p:null),class:"wide-card-input w-full",disabled:e(c),placeholder:"请输入您的 API Key (cr_...)",type:"password",onKeyup:s[3]||(s[3]=st((...p)=>e(x)&&e(x)(...p),["enter"]))},null,40,jt)),[[et,e(a)]])]),t("div",Et,[t("button",{class:"btn btn-primary btn-query flex h-full w-full items-center justify-center gap-2",disabled:e(c)||!b.value,onClick:s[7]||(s[7]=(...p)=>e(x)&&e(x)(...p))},[e(c)?(l(),n("i",Nt)):(l(),n("i",Ot)),f(" "+r(e(c)?"查询中...":"查询统计"),1)],8,Ft)])]),t("div",Bt,[s[13]||(s[13]=t("i",{class:"fas fa-shield-alt mr-2"},null,-1)),f(" "+r(e(m)?"您的 API Keys 仅用于查询统计数据,不会被存储。聚合模式下部分个体化信息将不显示。":"您的 API Key 仅用于查询自己的统计数据,不会被存储或用于其他用途"),1)]),e(m)?(l(),n("div",Vt,s[14]||(s[14]=[t("i",{class:"fas fa-lightbulb mr-2"},null,-1),t("span",null,"提示:最多支持同时查询 30 个 API Keys。使用 Ctrl+Enter 快速查询。",-1)]))):K("",!0)])]))}},Jt=O(Wt,[["__scopeId","data-v-11e74200"]]),zt={class:"mb-6 grid grid-cols-1 gap-4 md:mb-8 md:gap-6 lg:grid-cols-2"},Yt={class:"card p-4 md:p-6"},Ht={class:"mb-3 flex items-center text-lg font-bold text-gray-900 dark:text-gray-100 md:mb-4 md:text-xl"},Qt={key:0,class:"space-y-2 md:space-y-3"},Gt={class:"flex items-center justify-between"},Xt={class:"text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},Zt={class:"flex items-center justify-between"},te={class:"text-sm font-medium text-green-600 md:text-base"},ee={key:0,class:"flex items-center justify-between"},se={class:"text-sm font-medium text-red-600 md:text-base"},ae={class:"flex items-center justify-between"},re={class:"text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},ie={class:"flex items-center justify-between"},le={class:"text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},ne={class:"flex items-center justify-between"},oe={class:"text-sm font-medium text-indigo-600 md:text-base"},de={key:1,class:"border-t border-gray-200 pt-2 dark:border-gray-700"},me={class:"space-y-1"},ce={class:"truncate text-gray-600 dark:text-gray-400"},ue={class:"text-gray-900 dark:text-gray-100"},xe={key:1,class:"space-y-2 md:space-y-3"},ge={class:"flex items-center justify-between"},ye={class:"break-all text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},fe={class:"flex items-center justify-between"},pe={class:"flex items-center justify-between"},be={class:"text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},ve={class:"flex items-center justify-between"},ke={class:"break-all text-xs font-medium text-gray-900 dark:text-gray-100 md:text-base"},_e={class:"flex items-start justify-between"},he={key:0,class:"text-sm font-medium text-amber-600 dark:text-amber-500 md:text-base"},we={class:"ml-1 text-xs text-gray-500 dark:text-gray-400"},$e={key:1,class:"text-right"},Se={key:0,class:"text-sm font-medium text-red-600 md:text-base"},Ke={key:1,class:"break-all text-xs font-medium text-orange-600 md:text-base"},Ce={key:2,class:"break-all text-xs font-medium text-gray-900 dark:text-gray-100 md:text-base"},Te={key:2,class:"text-sm font-medium text-gray-400 dark:text-gray-500 md:text-base"},Ie={class:"card p-4 md:p-6"},Pe={class:"mb-3 flex flex-col text-lg font-bold text-gray-900 dark:text-gray-100 sm:flex-row sm:items-center md:mb-4 md:text-xl"},Le={class:"text-xs font-normal text-gray-600 dark:text-gray-400 sm:ml-2 md:text-sm"},Me={class:"grid grid-cols-2 gap-3 md:gap-4"},Ae={class:"stat-card text-center"},qe={class:"text-lg font-bold text-green-600 md:text-3xl"},De={class:"text-xs text-gray-600 dark:text-gray-400 md:text-sm"},je={class:"stat-card text-center"},Re={class:"text-lg font-bold text-blue-600 md:text-3xl"},Ue={class:"text-xs text-gray-600 dark:text-gray-400 md:text-sm"},Ee={class:"stat-card text-center"},Fe={class:"text-lg font-bold text-purple-600 md:text-3xl"},Ne={class:"text-xs text-gray-600 dark:text-gray-400 md:text-sm"},Oe={class:"stat-card text-center"},Be={class:"text-lg font-bold text-yellow-600 md:text-3xl"},Ve={class:"text-xs text-gray-600 dark:text-gray-400 md:text-sm"},We={__name:"StatsOverview",setup(P){const u=B(),{statsData:a,statsPeriod:c,currentPeriodData:m,multiKeyMode:x,aggregatedStats:d,individualStats:y,invalidKeys:b}=N(u),v=E(()=>!y.value||y.value.length===0?[]:[...y.value].sort((g,o)=>{var I,q;return(((I=o.usage)==null?void 0:I.allTokens)||0)-(((q=g.usage)==null?void 0:q.allTokens)||0)}).slice(0,3)),s=g=>{var I;return!d.value||!d.value.usage.allTokens?0:((((I=g.usage)==null?void 0:I.allTokens)||0)/d.value.usage.allTokens*100).toFixed(1)},p=g=>{if(!g)return"无";try{return wt(g).format("YYYY年MM月DD日 HH:mm")}catch{return"格式错误"}},A=g=>g?new Date(g).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}):"",w=g=>g?new Date(g)<new Date:!1,$=g=>{if(!g)return!1;const q=(new Date(g)-new Date)/(1e3*60*60*24);return q>0&&q<=7},k=g=>(typeof g!="number"&&(g=parseInt(g)||0),g===0?"0":g>=1e6?(g/1e6).toFixed(1)+"M":g>=1e3?(g/1e3).toFixed(1)+"K":g.toLocaleString()),S=g=>({claude:"Claude",gemini:"Gemini",all:"全部模型"})[g]||g||"未知";return(g,o)=>(l(),n("div",zt,[t("div",Yt,[t("h3",Ht,[t("i",{class:D(["mr-2 text-sm md:mr-3 md:text-base",e(x)?"fas fa-layer-group text-purple-500":"fas fa-info-circle text-blue-500"])},null,2),f(" "+r(e(x)?"批量查询概要":"API Key 信息"),1)]),e(x)&&e(d)?(l(),n("div",Qt,[t("div",Gt,[o[0]||(o[0]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"查询 Keys 数",-1)),t("span",Xt,r(e(d).totalKeys)+" 个 ",1)]),t("div",Zt,[o[2]||(o[2]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"有效 Keys 数",-1)),t("span",te,[o[1]||(o[1]=t("i",{class:"fas fa-check-circle mr-1 text-xs md:text-sm"},null,-1)),f(" "+r(e(d).activeKeys)+" 个 ",1)])]),e(b).length>0?(l(),n("div",ee,[o[4]||(o[4]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"无效 Keys 数",-1)),t("span",se,[o[3]||(o[3]=t("i",{class:"fas fa-times-circle mr-1 text-xs md:text-sm"},null,-1)),f(" "+r(e(b).length)+" 个 ",1)])])):K("",!0),t("div",ae,[o[5]||(o[5]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"总请求数",-1)),t("span",re,r(k(e(d).usage.requests)),1)]),t("div",ie,[o[6]||(o[6]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"总 Token 数",-1)),t("span",le,r(k(e(d).usage.allTokens)),1)]),t("div",ne,[o[7]||(o[7]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"总费用",-1)),t("span",oe,r(e(d).usage.formattedCost),1)]),e(y).length>1?(l(),n("div",de,[o[8]||(o[8]=t("div",{class:"mb-2 text-xs text-gray-500 dark:text-gray-400"},"各 Key 贡献占比",-1)),t("div",me,[(l(!0),n(J,null,z(v.value,I=>(l(),n("div",{key:I.apiId,class:"flex items-center justify-between text-xs"},[t("span",ce,r(I.name),1),t("span",ue,r(s(I))+"%",1)]))),128))])])):K("",!0)])):(l(),n("div",xe,[t("div",ge,[o[9]||(o[9]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"名称",-1)),t("span",ye,r(e(a).name),1)]),t("div",fe,[o[10]||(o[10]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"状态",-1)),t("span",{class:D(["text-sm font-medium md:text-base",e(a).isActive?"text-green-600":"text-red-600"])},[t("i",{class:D(["mr-1 text-xs md:text-sm",e(a).isActive?"fas fa-check-circle":"fas fa-times-circle"])},null,2),f(" "+r(e(a).isActive?"活跃":"已停用"),1)],2)]),t("div",pe,[o[11]||(o[11]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"权限",-1)),t("span",be,r(S(e(a).permissions)),1)]),t("div",ve,[o[12]||(o[12]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"创建时间",-1)),t("span",ke,r(p(e(a).createdAt)),1)]),t("div",_e,[o[18]||(o[18]=t("span",{class:"mt-1 flex-shrink-0 text-sm text-gray-600 dark:text-gray-400 md:text-base"},"过期时间",-1)),e(a).expirationMode==="activation"&&!e(a).isActivated?(l(),n("div",he,[o[13]||(o[13]=t("i",{class:"fas fa-pause-circle mr-1 text-xs md:text-sm"},null,-1)),o[14]||(o[14]=f(" 未激活 ",-1)),t("span",we,"(首次使用后"+r(e(a).activationDays||30)+"天过期)",1)])):e(a).expiresAt?(l(),n("div",$e,[w(e(a).expiresAt)?(l(),n("div",Se,o[15]||(o[15]=[t("i",{class:"fas fa-exclamation-circle mr-1 text-xs md:text-sm"},null,-1),f(" 已过期 ",-1)]))):$(e(a).expiresAt)?(l(),n("div",Ke,[o[16]||(o[16]=t("i",{class:"fas fa-clock mr-1 text-xs md:text-sm"},null,-1)),f(" "+r(A(e(a).expiresAt)),1)])):(l(),n("div",Ce,r(A(e(a).expiresAt)),1))])):(l(),n("div",Te,o[17]||(o[17]=[t("i",{class:"fas fa-infinity mr-1 text-xs md:text-sm"},null,-1),f(" 永不过期 ",-1)])))])]))]),t("div",Ie,[t("h3",Pe,[o[19]||(o[19]=t("span",{class:"flex items-center"},[t("i",{class:"fas fa-chart-bar mr-2 text-sm text-green-500 md:mr-3 md:text-base"}),f(" 使用统计概览 ")],-1)),t("span",Le,"("+r(e(c)==="daily"?"今日":"本月")+")",1)]),t("div",Me,[t("div",Ae,[t("div",qe,r(k(e(m).requests)),1),t("div",De,r(e(c)==="daily"?"今日":"本月")+"请求数 ",1)]),t("div",je,[t("div",Re,r(k(e(m).allTokens)),1),t("div",Ue,r(e(c)==="daily"?"今日":"本月")+"Token数 ",1)]),t("div",Ee,[t("div",Fe,r(e(m).formattedCost||"$0.000000"),1),t("div",Ne,r(e(c)==="daily"?"今日":"本月")+"费用 ",1)]),t("div",Oe,[t("div",Be,r(k(e(m).inputTokens)),1),t("div",Ve,r(e(c)==="daily"?"今日":"本月")+"输入Token ",1)])])])]))}},Je=O(We,[["__scopeId","data-v-9fc7e5f7"]]),ze={class:"card p-4 md:p-6"},Ye={class:"mb-3 flex flex-col text-lg font-bold text-gray-900 dark:text-gray-100 sm:flex-row sm:items-center md:mb-4 md:text-xl"},He={class:"text-xs font-normal text-gray-600 dark:text-gray-400 sm:ml-2 md:text-sm"},Qe={class:"space-y-2 md:space-y-3"},Ge={class:"flex items-center justify-between"},Xe={class:"text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},Ze={class:"flex items-center justify-between"},ts={class:"text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},es={class:"flex items-center justify-between"},ss={class:"text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},as={class:"flex items-center justify-between"},rs={class:"text-sm font-medium text-gray-900 dark:text-gray-100 md:text-base"},is={class:"mt-3 border-t border-gray-200 pt-3 dark:border-gray-700 md:mt-4 md:pt-4"},ls={class:"flex items-center justify-between font-bold text-gray-900 dark:text-gray-100"},ns={class:"text-sm md:text-base"},os={class:"text-lg md:text-xl"},ds={__name:"TokenDistribution",setup(P){const u=B(),{statsPeriod:a,currentPeriodData:c}=N(u),m=x=>(typeof x!="number"&&(x=parseInt(x)||0),x===0?"0":x>=1e6?(x/1e6).toFixed(1)+"M":x>=1e3?(x/1e3).toFixed(1)+"K":x.toLocaleString());return(x,d)=>(l(),n("div",ze,[t("h3",Ye,[d[0]||(d[0]=t("span",{class:"flex items-center"},[t("i",{class:"fas fa-coins mr-2 text-sm text-yellow-500 md:mr-3 md:text-base"}),f(" Token 使用分布 ")],-1)),t("span",He,"("+r(e(a)==="daily"?"今日":"本月")+")",1)]),t("div",Qe,[t("div",Ge,[d[1]||(d[1]=t("span",{class:"flex items-center text-sm text-gray-600 dark:text-gray-400 md:text-base"},[t("i",{class:"fas fa-arrow-right mr-1 text-xs text-green-500 md:mr-2 md:text-sm"}),f(" 输入 Token ")],-1)),t("span",Xe,r(m(e(c).inputTokens)),1)]),t("div",Ze,[d[2]||(d[2]=t("span",{class:"flex items-center text-sm text-gray-600 dark:text-gray-400 md:text-base"},[t("i",{class:"fas fa-arrow-left mr-1 text-xs text-blue-500 md:mr-2 md:text-sm"}),f(" 输出 Token ")],-1)),t("span",ts,r(m(e(c).outputTokens)),1)]),t("div",es,[d[3]||(d[3]=t("span",{class:"flex items-center text-sm text-gray-600 dark:text-gray-400 md:text-base"},[t("i",{class:"fas fa-save mr-1 text-xs text-purple-500 md:mr-2 md:text-sm"}),f(" 缓存创建 Token ")],-1)),t("span",ss,r(m(e(c).cacheCreateTokens)),1)]),t("div",as,[d[4]||(d[4]=t("span",{class:"flex items-center text-sm text-gray-600 dark:text-gray-400 md:text-base"},[t("i",{class:"fas fa-download mr-1 text-xs text-orange-500 md:mr-2 md:text-sm"}),f(" 缓存读取 Token ")],-1)),t("span",rs,r(m(e(c).cacheReadTokens)),1)])]),t("div",is,[t("div",ls,[t("span",ns,r(e(a)==="daily"?"今日":"本月")+"总计",1),t("span",os,r(m(e(c).allTokens)),1)])])]))}},ms=O(ds,[["__scopeId","data-v-ecee0a94"]]),cs={class:"card p-4 md:p-6"},us={class:"mb-3 flex items-center text-lg font-bold text-gray-900 dark:text-gray-100 md:mb-4 md:text-xl"},xs={key:0,class:"space-y-4"},gs={class:"rounded-lg bg-gradient-to-r from-blue-50 to-indigo-50 p-4 dark:from-blue-900/20 dark:to-indigo-900/20"},ys={class:"mb-3 flex items-center justify-between"},fs={class:"rounded-full bg-blue-100 px-2 py-1 text-xs font-semibold text-blue-700 dark:bg-blue-800 dark:text-blue-200"},ps={class:"grid grid-cols-2 gap-3"},bs={class:"text-center"},vs={class:"text-lg font-bold text-gray-900 dark:text-gray-100"},ks={class:"text-center"},_s={class:"text-lg font-bold text-green-600"},hs={class:"rounded-lg bg-gradient-to-r from-purple-50 to-pink-50 p-4 dark:from-purple-900/20 dark:to-pink-900/20"},ws={class:"space-y-2"},$s={class:"flex items-center justify-between"},Ss={class:"text-sm font-medium text-gray-900 dark:text-gray-100"},Ks={class:"flex items-center justify-between"},Cs={class:"text-sm font-medium text-gray-900 dark:text-gray-100"},Ts={class:"flex items-center justify-between"},Is={class:"text-sm font-medium text-gray-900 dark:text-gray-100"},Ps={key:0,class:"rounded-lg bg-red-50 p-3 text-sm dark:bg-red-900/20"},Ls={class:"text-red-700 dark:text-red-300"},Ms={key:1,class:"space-y-4 md:space-y-5"},As={class:"mb-2 flex items-center justify-between"},qs={class:"text-xs text-gray-500 dark:text-gray-400 md:text-sm"},Ds={key:0},js={key:1,class:"flex items-center gap-1"},Rs={key:0,class:"h-2 w-full rounded-full bg-gray-200 dark:bg-gray-700"},Us={key:1,class:"h-2 w-full rounded-full bg-gray-200"},Es={key:0},Fs={class:"mt-2 text-xs text-gray-500 dark:text-gray-400"},Ns={key:0},Os={key:1},Bs={key:2},Vs={class:"space-y-2 border-t border-gray-100 pt-2 dark:border-gray-700"},Ws={class:"flex items-center justify-between"},Js={class:"text-sm font-medium text-gray-900 md:text-base"},zs={key:0},Ys={key:1,class:"flex items-center gap-1"},Hs={class:"flex items-center justify-between"},Qs={class:"text-sm font-medium text-gray-900 md:text-base"},Gs={key:0,class:"text-orange-600"},Xs={key:1,class:"text-green-600"},Zs={class:"flex items-center justify-between"},ta={class:"text-sm font-medium text-gray-900 md:text-base"},ea={key:0,class:"text-orange-600"},sa={key:1,class:"text-green-600"},aa={key:0,class:"card mt-4 p-4 md:mt-6 md:p-6"},ra={class:"grid grid-cols-1 gap-4 md:gap-6 lg:grid-cols-2"},ia={key:0,class:"rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-800 dark:bg-amber-900/20 md:p-4"},la={class:"space-y-1 md:space-y-2"},na={class:"break-all text-gray-800 dark:text-gray-200"},oa={key:1,class:"rounded-lg border border-blue-200 bg-blue-50 p-3 dark:border-blue-800 dark:bg-blue-900/20 md:p-4"},da={class:"space-y-1 md:space-y-2"},ma={class:"break-all text-gray-800 dark:text-gray-200"},ca={__name:"LimitConfig",setup(P){const u=B(),{statsData:a,multiKeyMode:c,aggregatedStats:m,invalidKeys:x}=N(u),d=()=>{if(!a.value.limits.dailyCostLimit||a.value.limits.dailyCostLimit===0)return 0;const v=a.value.limits.currentDailyCost/a.value.limits.dailyCostLimit*100;return Math.min(v,100)},y=()=>{const v=d();return v>=100?"bg-red-500":v>=80?"bg-yellow-500":"bg-green-500"},b=v=>(typeof v!="number"&&(v=parseInt(v)||0),v===0?"0":v>=1e6?(v/1e6).toFixed(1)+"M":v>=1e3?(v/1e3).toFixed(1)+"K":v.toLocaleString());return(v,s)=>(l(),n("div",null,[t("div",cs,[t("h3",us,[s[0]||(s[0]=t("i",{class:"fas fa-shield-alt mr-2 text-sm text-red-500 md:mr-3 md:text-base"},null,-1)),f(" "+r(e(c)?"限制配置(聚合查询模式)":"限制配置"),1)]),e(c)&&e(m)?(l(),n("div",xs,[t("div",gs,[t("div",ys,[s[1]||(s[1]=t("span",{class:"text-sm font-medium text-gray-700 dark:text-gray-300"},[t("i",{class:"fas fa-layer-group mr-2 text-blue-500"}),f(" API Keys 概况 ")],-1)),t("span",fs,r(e(m).activeKeys)+"/"+r(e(m).totalKeys),1)]),t("div",ps,[t("div",bs,[t("div",vs,r(e(m).totalKeys),1),s[2]||(s[2]=t("div",{class:"text-xs text-gray-600 dark:text-gray-400"},"总计 Keys",-1))]),t("div",ks,[t("div",_s,r(e(m).activeKeys),1),s[3]||(s[3]=t("div",{class:"text-xs text-gray-600 dark:text-gray-400"},"激活 Keys",-1))])])]),t("div",hs,[s[7]||(s[7]=t("div",{class:"mb-3 flex items-center"},[t("i",{class:"fas fa-chart-pie mr-2 text-purple-500"}),t("span",{class:"text-sm font-medium text-gray-700 dark:text-gray-300"},"聚合统计摘要")],-1)),t("div",ws,[t("div",$s,[s[4]||(s[4]=t("span",{class:"text-xs text-gray-600 dark:text-gray-400"},[t("i",{class:"fas fa-database mr-1 text-gray-400"}),f(" 总请求数 ")],-1)),t("span",Ss,r(b(e(m).usage.requests)),1)]),t("div",Ks,[s[5]||(s[5]=t("span",{class:"text-xs text-gray-600 dark:text-gray-400"},[t("i",{class:"fas fa-coins mr-1 text-yellow-500"}),f(" 总 Tokens ")],-1)),t("span",Cs,r(b(e(m).usage.allTokens)),1)]),t("div",Ts,[s[6]||(s[6]=t("span",{class:"text-xs text-gray-600 dark:text-gray-400"},[t("i",{class:"fas fa-dollar-sign mr-1 text-green-500"}),f(" 总费用 ")],-1)),t("span",Is,r(e(m).usage.formattedCost),1)])])]),e(x)&&e(x).length>0?(l(),n("div",Ps,[s[8]||(s[8]=t("i",{class:"fas fa-exclamation-triangle mr-2 text-red-600 dark:text-red-400"},null,-1)),t("span",Ls,r(e(x).length)+" 个无效的 API Key ",1)])):K("",!0),s[9]||(s[9]=t("div",{class:"rounded-lg bg-gray-50 p-3 text-xs text-gray-600 dark:bg-gray-800 dark:text-gray-400"},[t("i",{class:"fas fa-info-circle mr-1"}),f(" 每个 API Key 有独立的限制设置,聚合模式下不显示单个限制配置 ")],-1))])):K("",!0),e(c)?K("",!0):(l(),n("div",Ms,[t("div",null,[t("div",As,[s[11]||(s[11]=t("span",{class:"text-sm font-medium text-gray-600 dark:text-gray-400 md:text-base"},"每日费用限制",-1)),t("span",qs,[e(a).limits.dailyCostLimit>0?(l(),n("span",Ds," $"+r(e(a).limits.currentDailyCost.toFixed(4))+" / $"+r(e(a).limits.dailyCostLimit.toFixed(2)),1)):(l(),n("span",js,[f(" $"+r(e(a).limits.currentDailyCost.toFixed(4))+" / ",1),s[10]||(s[10]=t("i",{class:"fas fa-infinity"},null,-1))]))])]),e(a).limits.dailyCostLimit>0?(l(),n("div",Rs,[t("div",{class:D(["h-2 rounded-full transition-all duration-300",y()]),style:it({width:d()+"%"})},null,6)])):(l(),n("div",Us,s[12]||(s[12]=[t("div",{class:"h-2 rounded-full bg-green-500",style:{width:"0%"}},null,-1)])))]),e(a).limits.rateLimitWindow>0&&(e(a).limits.rateLimitRequests>0||e(a).limits.tokenLimit>0||e(a).limits.rateLimitCost>0)?(l(),n("div",Es,[U($t,{"cost-limit":e(a).limits.rateLimitCost,"current-cost":e(a).limits.currentWindowCost,"current-requests":e(a).limits.currentWindowRequests,"current-tokens":e(a).limits.currentWindowTokens,label:"时间窗口限制","rate-limit-window":e(a).limits.rateLimitWindow,"request-limit":e(a).limits.rateLimitRequests,"show-progress":!0,"show-tooltip":!0,"token-limit":e(a).limits.tokenLimit,"window-end-time":e(a).limits.windowEndTime,"window-remaining-seconds":e(a).limits.windowRemainingSeconds,"window-start-time":e(a).limits.windowStartTime},null,8,["cost-limit","current-cost","current-requests","current-tokens","rate-limit-window","request-limit","token-limit","window-end-time","window-remaining-seconds","window-start-time"]),t("div",Fs,[s[13]||(s[13]=t("i",{class:"fas fa-info-circle mr-1"},null,-1)),e(a).limits.rateLimitCost>0?(l(),n("span",Ns,' 请求次数和费用限制为"或"的关系,任一达到限制即触发限流 ')):e(a).limits.tokenLimit>0?(l(),n("span",Os,' 请求次数和Token使用量为"或"的关系,任一达到限制即触发限流 ')):(l(),n("span",Bs," 仅限制请求次数 "))])])):K("",!0),t("div",Vs,[t("div",Ws,[s[15]||(s[15]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"并发限制",-1)),t("span",Js,[e(a).limits.concurrencyLimit>0?(l(),n("span",zs,r(e(a).limits.concurrencyLimit),1)):(l(),n("span",Ys,s[14]||(s[14]=[t("i",{class:"fas fa-infinity text-gray-400"},null,-1)])))])]),t("div",Hs,[s[18]||(s[18]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"模型限制",-1)),t("span",Qs,[e(a).restrictions.enableModelRestriction&&e(a).restrictions.restrictedModels.length>0?(l(),n("span",Gs,[s[16]||(s[16]=t("i",{class:"fas fa-exclamation-triangle mr-1 text-xs md:text-sm"},null,-1)),f(" 限制 "+r(e(a).restrictions.restrictedModels.length)+" 个模型 ",1)])):(l(),n("span",Xs,s[17]||(s[17]=[t("i",{class:"fas fa-check-circle mr-1 text-xs md:text-sm"},null,-1),f(" 允许所有模型 ",-1)])))])]),t("div",Zs,[s[21]||(s[21]=t("span",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"客户端限制",-1)),t("span",ta,[e(a).restrictions.enableClientRestriction&&e(a).restrictions.allowedClients.length>0?(l(),n("span",ea,[s[19]||(s[19]=t("i",{class:"fas fa-exclamation-triangle mr-1 text-xs md:text-sm"},null,-1)),f(" 限制 "+r(e(a).restrictions.allowedClients.length)+" 个客户端 ",1)])):(l(),n("span",sa,s[20]||(s[20]=[t("i",{class:"fas fa-check-circle mr-1 text-xs md:text-sm"},null,-1),f(" 允许所有客户端 ",-1)])))])])])]))]),e(a).restrictions.enableModelRestriction&&e(a).restrictions.restrictedModels.length>0||e(a).restrictions.enableClientRestriction&&e(a).restrictions.allowedClients.length>0?(l(),n("div",aa,[s[28]||(s[28]=t("h3",{class:"mb-3 flex items-center text-lg font-bold text-gray-900 dark:text-gray-100 md:mb-4 md:text-xl"},[t("i",{class:"fas fa-list-alt mr-2 text-sm text-amber-500 md:mr-3 md:text-base"}),f(" 详细限制信息 ")],-1)),t("div",ra,[e(a).restrictions.enableModelRestriction&&e(a).restrictions.restrictedModels.length>0?(l(),n("div",ia,[s[23]||(s[23]=t("h4",{class:"mb-2 flex items-center text-sm font-bold text-amber-800 dark:text-amber-300 md:mb-3 md:text-base"},[t("i",{class:"fas fa-robot mr-1 text-xs md:mr-2 md:text-sm"}),f(" 受限模型列表 ")],-1)),t("div",la,[(l(!0),n(J,null,z(e(a).restrictions.restrictedModels,p=>(l(),n("div",{key:p,class:"rounded border border-amber-200 bg-white px-2 py-1 text-xs dark:border-amber-700 dark:bg-gray-800 md:px-3 md:py-2 md:text-sm"},[s[22]||(s[22]=t("i",{class:"fas fa-ban mr-1 text-xs text-red-500 md:mr-2"},null,-1)),t("span",na,r(p),1)]))),128))]),s[24]||(s[24]=t("p",{class:"mt-2 text-xs text-amber-700 dark:text-amber-400 md:mt-3"},[t("i",{class:"fas fa-info-circle mr-1"}),f(" 此 API Key 不能访问以上列出的模型 ")],-1))])):K("",!0),e(a).restrictions.enableClientRestriction&&e(a).restrictions.allowedClients.length>0?(l(),n("div",oa,[s[26]||(s[26]=t("h4",{class:"mb-2 flex items-center text-sm font-bold text-blue-800 dark:text-blue-300 md:mb-3 md:text-base"},[t("i",{class:"fas fa-desktop mr-1 text-xs md:mr-2 md:text-sm"}),f(" 允许的客户端 ")],-1)),t("div",da,[(l(!0),n(J,null,z(e(a).restrictions.allowedClients,p=>(l(),n("div",{key:p,class:"rounded border border-blue-200 bg-white px-2 py-1 text-xs dark:border-blue-700 dark:bg-gray-800 md:px-3 md:py-2 md:text-sm"},[s[25]||(s[25]=t("i",{class:"fas fa-check mr-1 text-xs text-green-500 md:mr-2"},null,-1)),t("span",ma,r(p),1)]))),128))]),s[27]||(s[27]=t("p",{class:"mt-2 text-xs text-blue-700 dark:text-blue-400 md:mt-3"},[t("i",{class:"fas fa-info-circle mr-1"}),f(" 此 API Key 只能被以上列出的客户端使用 ")],-1))])):K("",!0)])])):K("",!0)]))}},ua=O(ca,[["__scopeId","data-v-01a13ba5"]]),xa={class:"card h-full p-4 md:p-6"},ga={class:"mb-3 flex flex-col text-lg font-bold text-gray-900 dark:text-gray-100 sm:flex-row sm:items-center md:mb-4 md:text-xl"},ya={class:"text-xs font-normal text-gray-600 dark:text-gray-400 sm:ml-2 md:text-sm"},fa={key:0,class:"space-y-2 md:space-y-3"},pa={class:"mb-1 flex items-center justify-between text-sm"},ba={class:"truncate font-medium text-gray-700 dark:text-gray-300"},va={class:"text-xs text-gray-600 dark:text-gray-400"},ka={class:"h-2 w-full rounded-full bg-gray-200 dark:bg-gray-700"},_a={class:"mt-1 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400"},ha={key:0,class:"border-t border-gray-200 pt-2 dark:border-gray-700"},wa={class:"flex items-center justify-between text-sm text-gray-600 dark:text-gray-400"},$a={key:1,class:"flex h-32 items-center justify-center text-sm text-gray-500 dark:text-gray-400"},Sa={key:2,class:"flex h-32 items-center justify-center text-sm text-gray-500 dark:text-gray-400"},Ka={__name:"AggregatedStatsCard",setup(P){const u=B(),{aggregatedStats:a,individualStats:c,statsPeriod:m,multiKeyMode:x}=N(u),d=w=>w?m.value==="daily"?w.dailyUsage||w.usage:w.monthlyUsage||w.usage:null,y=E(()=>!c.value||c.value.length===0?[]:[...c.value].sort((w,$)=>{const k=d(w),S=d($);return((S==null?void 0:S.cost)||0)-((k==null?void 0:k.cost)||0)}).slice(0,5)),b=E(()=>c.value?Math.max(0,c.value.length-5):0),v=E(()=>{var S,g;if(!c.value||!a.value)return 0;const w=y.value.reduce((o,I)=>{const q=d(I);return o+((q==null?void 0:q.cost)||0)},0),$=m.value==="daily"?((S=a.value.dailyUsage)==null?void 0:S.cost)||0:((g=a.value.monthlyUsage)==null?void 0:g.cost)||0;if($===0)return 0;const k=$-w;return Math.max(0,Math.round(k/$*100))}),s=w=>{var g,o;if(!a.value)return 0;const $=m.value==="daily"?((g=a.value.dailyUsage)==null?void 0:g.cost)||0:((o=a.value.monthlyUsage)==null?void 0:o.cost)||0;if($===0)return 0;const k=d(w),S=((k==null?void 0:k.cost)||0)/$*100;return Math.round(S)},p=w=>["bg-blue-500","bg-green-500","bg-purple-500","bg-yellow-500","bg-pink-500"][w]||"bg-gray-400",A=w=>(typeof w!="number"&&(w=parseInt(w)||0),w===0?"0":w>=1e6?(w/1e6).toFixed(1)+"M":w>=1e3?(w/1e3).toFixed(1)+"K":w.toLocaleString());return(w,$)=>(l(),n("div",xa,[t("h3",ga,[$[0]||($[0]=t("span",{class:"flex items-center"},[t("i",{class:"fas fa-chart-pie mr-2 text-sm text-orange-500 md:mr-3 md:text-base"}),f(" 使用占比 ")],-1)),t("span",ya,"("+r(e(m)==="daily"?"今日":"本月")+")",1)]),e(a)&&e(c).length>0?(l(),n("div",fa,[(l(!0),n(J,null,z(y.value,(k,S)=>{var g,o;return l(),n("div",{key:k.apiId,class:"relative"},[t("div",pa,[t("span",ba,r(k.name||`Key ${S+1}`),1),t("span",va,r(s(k))+"% ",1)]),t("div",ka,[t("div",{class:D(["h-2 rounded-full transition-all duration-300",p(S)]),style:it({width:s(k)+"%"})},null,6)]),t("div",_a,[t("span",null,r(A(((g=d(k))==null?void 0:g.requests)||0))+"次",1),t("span",null,r(((o=d(k))==null?void 0:o.formattedCost)||"$0.00"),1)])])}),128)),b.value>0?(l(),n("div",ha,[t("div",wa,[t("span",null,"其他 "+r(b.value)+" 个Keys",1),t("span",null,r(v.value)+"%",1)])])):K("",!0)])):e(x)?(l(),n("div",Sa,$[2]||($[2]=[t("i",{class:"fas fa-chart-pie mr-2"},null,-1),f(" 暂无数据 ",-1)]))):(l(),n("div",$a,$[1]||($[1]=[t("div",{class:"text-center"},[t("i",{class:"fas fa-chart-pie mb-2 text-2xl"}),t("p",null,"使用占比仅在多Key查询时显示")],-1)])))]))}},Ca=O(Ka,[["__scopeId","data-v-39572a8e"]]),Ta={class:"card p-4 md:p-6"},Ia={class:"mb-4 md:mb-6"},Pa={class:"flex flex-col text-lg font-bold text-gray-900 dark:text-gray-100 sm:flex-row sm:items-center md:text-xl"},La={class:"text-xs font-normal text-gray-600 dark:text-gray-400 sm:ml-2 md:text-sm"},Ma={key:0,class:"py-6 text-center md:py-8"},Aa={key:1,class:"space-y-3 md:space-y-4"},qa={class:"mb-2 flex items-start justify-between md:mb-3"},Da={class:"min-w-0 flex-1"},ja={class:"break-all text-base font-bold text-gray-900 dark:text-gray-100 md:text-lg"},Ra={class:"text-xs text-gray-600 dark:text-gray-400 md:text-sm"},Ua={class:"ml-3 flex-shrink-0 text-right"},Ea={class:"text-base font-bold text-green-600 md:text-lg"},Fa={class:"grid grid-cols-2 gap-2 text-xs md:grid-cols-4 md:gap-3 md:text-sm"},Na={class:"rounded bg-gray-50 p-2 dark:bg-gray-700"},Oa={class:"font-medium text-gray-900 dark:text-gray-100"},Ba={class:"rounded bg-gray-50 p-2 dark:bg-gray-700"},Va={class:"font-medium text-gray-900 dark:text-gray-100"},Wa={class:"rounded bg-gray-50 p-2 dark:bg-gray-700"},Ja={class:"font-medium text-gray-900 dark:text-gray-100"},za={class:"rounded bg-gray-50 p-2 dark:bg-gray-700"},Ya={class:"font-medium text-gray-900 dark:text-gray-100"},Ha={key:2,class:"py-6 text-center text-gray-500 dark:text-gray-400 md:py-8"},Qa={class:"text-sm md:text-base"},Ga={__name:"ModelUsageStats",setup(P){const u=B(),{statsPeriod:a,modelStats:c,modelStatsLoading:m}=N(u),x=d=>(typeof d!="number"&&(d=parseInt(d)||0),d===0?"0":d>=1e6?(d/1e6).toFixed(1)+"M":d>=1e3?(d/1e3).toFixed(1)+"K":d.toLocaleString());return(d,y)=>(l(),n("div",Ta,[t("div",Ia,[t("h3",Pa,[y[0]||(y[0]=t("span",{class:"flex items-center"},[t("i",{class:"fas fa-robot mr-2 text-sm text-indigo-500 md:mr-3 md:text-base"}),f(" 模型使用统计 ")],-1)),t("span",La,"("+r(e(a)==="daily"?"今日":"本月")+")",1)])]),e(m)?(l(),n("div",Ma,y[1]||(y[1]=[t("i",{class:"fas fa-spinner loading-spinner mb-2 text-xl text-gray-600 dark:text-gray-400 md:text-2xl"},null,-1),t("p",{class:"text-sm text-gray-600 dark:text-gray-400 md:text-base"},"加载模型统计数据中...",-1)]))):e(c).length>0?(l(),n("div",Aa,[(l(!0),n(J,null,z(e(c),(b,v)=>{var s;return l(),n("div",{key:v,class:"model-usage-item"},[t("div",qa,[t("div",Da,[t("h4",ja,r(b.model),1),t("p",Ra,r(b.requests)+" 次请求 ",1)]),t("div",Ua,[t("div",Ea,r(((s=b.formatted)==null?void 0:s.total)||"$0.000000"),1),y[2]||(y[2]=t("div",{class:"text-xs text-gray-600 dark:text-gray-400 md:text-sm"},"总费用",-1))])]),t("div",Fa,[t("div",Na,[y[3]||(y[3]=t("div",{class:"text-gray-600 dark:text-gray-400"},"输入 Token",-1)),t("div",Oa,r(x(b.inputTokens)),1)]),t("div",Ba,[y[4]||(y[4]=t("div",{class:"text-gray-600 dark:text-gray-400"},"输出 Token",-1)),t("div",Va,r(x(b.outputTokens)),1)]),t("div",Wa,[y[5]||(y[5]=t("div",{class:"text-gray-600 dark:text-gray-400"},"缓存创建",-1)),t("div",Ja,r(x(b.cacheCreateTokens)),1)]),t("div",za,[y[6]||(y[6]=t("div",{class:"text-gray-600 dark:text-gray-400"},"缓存读取",-1)),t("div",Ya,r(x(b.cacheReadTokens)),1)])])])}),128))])):(l(),n("div",Ha,[y[7]||(y[7]=t("i",{class:"fas fa-chart-pie mb-3 text-2xl md:text-3xl"},null,-1)),t("p",Qa," 暂无"+r(e(a)==="daily"?"今日":"本月")+"模型使用数据 ",1)]))]))}},Xa=O(Ga,[["__scopeId","data-v-b3b8dc5f"]]),Za={class:"glass-strong mb-6 rounded-3xl p-4 shadow-xl md:mb-8 md:p-6"},tr={class:"flex flex-col items-center justify-between gap-4 md:flex-row"},er={class:"flex items-center gap-2 md:gap-4"},sr={class:"flex items-center"},ar={class:"mb-6 md:mb-8"},rr={class:"flex justify-center"},ir={class:"inline-flex w-full max-w-md rounded-full border border-white/20 bg-white/10 p-1 shadow-lg backdrop-blur-xl md:w-auto"},lr={key:0,class:"tab-content"},nr={key:0,class:"mb-6 md:mb-8"},or={class:"rounded-xl border border-red-500/30 bg-red-500/20 p-3 text-sm text-red-800 backdrop-blur-sm dark:border-red-500/20 dark:bg-red-500/10 dark:text-red-200 md:p-4 md:text-base"},dr={key:1,class:"fade-in"},mr={class:"glass-strong rounded-3xl p-4 shadow-xl md:p-6"},cr={class:"mb-4 border-b border-gray-200 pb-4 dark:border-gray-700 md:mb-6 md:pb-6"},ur={class:"flex flex-col items-start justify-between gap-3 md:flex-row md:items-center md:gap-4"},xr={class:"flex w-full gap-2 md:w-auto"},gr=["disabled"],yr=["disabled"],fr={class:"mb-6 grid grid-cols-1 gap-4 md:mb-8 md:gap-6 lg:grid-cols-2"},pr={key:1,class:"tab-content"},br={class:"glass-strong rounded-3xl shadow-xl"},vr={__name:"ApiStatsView",setup(P){const u=ft(),a=B(),c=kt(),m=C("stats"),x=E(()=>c.isDarkMode),{apiKey:d,apiId:y,loading:b,modelStatsLoading:v,oemLoading:s,error:p,statsPeriod:A,statsData:w,oemSettings:$,multiKeyMode:k}=N(a),{queryStats:S,switchPeriod:g,loadStatsWithApiId:o,loadOemSettings:I,reset:q}=a,V=T=>{(T.ctrlKey||T.metaKey)&&T.key==="Enter"&&(!b.value&&d.value.trim()&&S(),T.preventDefault()),T.key==="Escape"&&q()};return yt(()=>{console.log("API Stats Page loaded"),c.initTheme(),I();const T=u.query.apiId,_=u.query.apiKey;T&&T.match(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i)?(y.value=T,o()):_&&_.length>10&&(d.value=_),document.addEventListener("keydown",V)}),pt(()=>{document.removeEventListener("keydown",V)}),bt(d,T=>{T||a.clearData()}),(T,_)=>{const Y=vt("router-link");return l(),n("div",{class:D(["min-h-screen p-4 md:p-6",x.value?"gradient-bg-dark":"gradient-bg"])},[t("div",Za,[t("div",tr,[U(_t,{loading:e(s),"logo-src":e($).siteIconData||e($).siteIcon,subtitle:m.value==="stats"?"API Key 使用统计":"使用教程",title:e($).siteName},null,8,["loading","logo-src","subtitle","title"]),t("div",er,[t("div",sr,[U(ht,{mode:"dropdown"})]),_[6]||(_[6]=t("div",{class:"h-8 w-px bg-gradient-to-b from-transparent via-gray-300 to-transparent opacity-50 dark:via-gray-600"},null,-1)),e($).ldapEnabled?(l(),Q(Y,{key:0,class:"user-login-button flex items-center gap-2 rounded-2xl px-4 py-2 text-white transition-all duration-300 md:px-5 md:py-2.5",to:"/user-login"},{default:rt(()=>_[4]||(_[4]=[t("i",{class:"fas fa-user text-sm md:text-base"},null,-1),t("span",{class:"text-xs font-semibold tracking-wide md:text-sm"},"用户登录",-1)])),_:1,__:[4]})):K("",!0),U(Y,{class:"admin-button-refined flex items-center gap-2 rounded-2xl px-4 py-2 transition-all duration-300 md:px-5 md:py-2.5",to:"/dashboard"},{default:rt(()=>_[5]||(_[5]=[t("i",{class:"fas fa-shield-alt text-sm md:text-base"},null,-1),t("span",{class:"text-xs font-semibold tracking-wide md:text-sm"},"管理后台",-1)])),_:1,__:[5]})])])]),t("div",ar,[t("div",rr,[t("div",ir,[t("button",{class:D(["tab-pill-button",m.value==="stats"?"active":""]),onClick:_[0]||(_[0]=W=>m.value="stats")},_[7]||(_[7]=[t("i",{class:"fas fa-chart-line mr-1 md:mr-2"},null,-1),t("span",{class:"text-sm md:text-base"},"统计查询",-1)]),2),t("button",{class:D(["tab-pill-button",m.value==="tutorial"?"active":""]),onClick:_[1]||(_[1]=W=>m.value="tutorial")},_[8]||(_[8]=[t("i",{class:"fas fa-graduation-cap mr-1 md:mr-2"},null,-1),t("span",{class:"text-sm md:text-base"},"使用教程",-1)]),2)])])]),m.value==="stats"?(l(),n("div",lr,[U(Jt),e(p)?(l(),n("div",nr,[t("div",or,[_[9]||(_[9]=t("i",{class:"fas fa-exclamation-triangle mr-2"},null,-1)),f(" "+r(e(p)),1)])])):K("",!0),e(w)?(l(),n("div",dr,[t("div",mr,[t("div",cr,[t("div",ur,[_[12]||(_[12]=t("div",{class:"flex items-center gap-2 md:gap-3"},[t("i",{class:"fas fa-clock text-base text-blue-500 md:text-lg"}),t("span",{class:"text-base font-medium text-gray-700 dark:text-gray-200 md:text-lg"},"统计时间范围")],-1)),t("div",xr,[t("button",{class:D(["flex flex-1 items-center justify-center gap-1 px-4 py-2 text-xs font-medium md:flex-none md:gap-2 md:px-6 md:text-sm",["period-btn",{active:e(A)==="daily"}]]),disabled:e(b)||e(v),onClick:_[2]||(_[2]=W=>e(g)("daily"))},_[10]||(_[10]=[t("i",{class:"fas fa-calendar-day text-xs md:text-sm"},null,-1),f(" 今日 ",-1)]),10,gr),t("button",{class:D(["flex flex-1 items-center justify-center gap-1 px-4 py-2 text-xs font-medium md:flex-none md:gap-2 md:px-6 md:text-sm",["period-btn",{active:e(A)==="monthly"}]]),disabled:e(b)||e(v),onClick:_[3]||(_[3]=W=>e(g)("monthly"))},_[11]||(_[11]=[t("i",{class:"fas fa-calendar-alt text-xs md:text-sm"},null,-1),f(" 本月 ",-1)]),10,yr)])])]),U(Je),t("div",fr,[U(ms),e(k)?K("",!0):(l(),Q(ua,{key:0})),e(k)?(l(),Q(Ca,{key:1})):K("",!0)]),U(Xa)])])):K("",!0)])):K("",!0),m.value==="tutorial"?(l(),n("div",pr,[t("div",br,[U(St)])])):K("",!0)],2)}}},Tr=O(vr,[["__scopeId","data-v-0b409494"]]);export{Tr as default};