Files
claude-relay-service/web/admin-spa/dist/assets/ApiKeysView-BzGygItQ.js

5 lines
60 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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

import{E as It}from"./element-plus-D-FTEVKS.js";import{aR as Mt,r as K,_ as lt,q as ot,c as J,I as q,y as r,z as t,Y as B,K as w,aq as M,O as f,x as d,L as A,aX as O,P as p,an as z,ac as E,Q as h,al as Y,aa as pt,a5 as Z,C as S,R as Rt,B as St}from"./vue-vendor-YmkKLAOK.js";import{s as D}from"./toast-BvwA7Mwb.js";import{a as V,_ as G,u as it}from"./index-BiAIsnvb.js";import"./vendor-BDiMbLwQ.js";const nt=Mt("clients",{state:()=>({supportedClients:[],loading:!1,error:null}),actions:{async loadSupportedClients(){if(this.supportedClients.length>0)return this.supportedClients;this.loading=!0,this.error=null;try{const k=await V.get("/admin/supported-clients");return k.success?this.supportedClients=k.data||[]:(this.error=k.message||"加载支持的客户端失败",console.error("Failed to load supported clients:",this.error)),this.supportedClients}catch(k){return this.error=k.message||"加载支持的客户端失败",console.error("Error loading supported clients:",k),[]}finally{this.loading=!1}}}}),ht={class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},Tt={class:"modal-content w-full max-w-md p-8 mx-auto max-h-[90vh] flex flex-col"},Et={class:"flex items-center justify-between mb-6"},Pt={class:"bg-blue-50 border border-blue-200 rounded-lg p-4 space-y-4"},jt={class:"space-y-3"},Vt={class:"flex gap-2"},_t={key:0,class:"mt-3"},Ut=["min"],qt={key:1,class:"text-xs text-gray-500 mt-2"},Ot={class:"flex gap-4"},Ft={class:"flex items-center cursor-pointer"},Wt={class:"flex items-center cursor-pointer"},zt={class:"flex items-center cursor-pointer"},Yt={class:"grid grid-cols-1 gap-3"},Nt=["disabled"],Ht=["value"],Bt=["disabled"],Gt=["value"],Xt={class:"flex items-center mb-3"},Qt={key:0,class:"space-y-3"},Jt={class:"flex flex-wrap gap-2 mb-3 min-h-[32px] p-2 bg-gray-50 rounded-lg border border-gray-200"},Zt=["onClick"],te={key:0,class:"text-gray-400 text-sm"},ee={class:"flex gap-2"},se=["onKeydown"],le={class:"flex items-center mb-3"},oe={key:0,class:"space-y-3"},ie={class:"space-y-2"},ne=["id","value"],ae=["for"],re={class:"text-sm font-medium text-gray-700"},de={class:"text-xs text-gray-500 block"},ue={class:"flex gap-3 pt-4"},me=["disabled"],pe={key:0,class:"loading-spinner mr-2"},ce={key:1,class:"fas fa-plus mr-2"},xe={__name:"CreateApiKeyModal",props:{accounts:{type:Object,default:()=>({claude:[],gemini:[]})}},emits:["close","success"],setup(k,{emit:_}){const C=_;it();const I=nt(),L=K(!1),x=K([]),i=lt({name:"",description:"",tokenLimit:"",rateLimitWindow:"",rateLimitRequests:"",concurrencyLimit:"",dailyCostLimit:"",expireDuration:"",customExpireDate:"",expiresAt:null,permissions:"all",claudeAccountId:"",geminiAccountId:"",enableModelRestriction:!1,restrictedModels:[],modelInput:"",enableClientRestriction:!1,allowedClients:[]});ot(async()=>{x.value=await I.loadSupportedClients()});const n=J(()=>{const b=new Date;return b.setMinutes(b.getMinutes()+1),b.toISOString().slice(0,16)}),$=()=>{if(!i.expireDuration){i.expiresAt=null;return}if(i.expireDuration==="custom")return;const b=new Date,u=i.expireDuration.match(/(\d+)([dhmy])/);if(u){const[,j,N]=u,F=parseInt(j);switch(N){case"d":b.setDate(b.getDate()+F);break;case"h":b.setHours(b.getHours()+F);break;case"m":b.setMonth(b.getMonth()+F);break;case"y":b.setFullYear(b.getFullYear()+F);break}i.expiresAt=b.toISOString()}},v=()=>{i.customExpireDate&&(i.expiresAt=new Date(i.customExpireDate).toISOString())},P=b=>new Date(b).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}),y=()=>{i.modelInput&&!i.restrictedModels.includes(i.modelInput)&&(i.restrictedModels.push(i.modelInput),i.modelInput="")},l=b=>{i.restrictedModels.splice(b,1)},m=async()=>{L.value=!0;try{const b={name:i.name,description:i.description||void 0,tokenLimit:i.tokenLimit!==""&&i.tokenLimit!==null?parseInt(i.tokenLimit):null,rateLimitWindow:i.rateLimitWindow!==""&&i.rateLimitWindow!==null?parseInt(i.rateLimitWindow):null,rateLimitRequests:i.rateLimitRequests!==""&&i.rateLimitRequests!==null?parseInt(i.rateLimitRequests):null,concurrencyLimit:i.concurrencyLimit!==""&&i.concurrencyLimit!==null?parseInt(i.concurrencyLimit):0,dailyCostLimit:i.dailyCostLimit!==""&&i.dailyCostLimit!==null?parseFloat(i.dailyCostLimit):0,expiresAt:i.expiresAt||void 0,permissions:i.permissions,claudeAccountId:i.claudeAccountId||void 0,geminiAccountId:i.geminiAccountId||void 0};i.enableModelRestriction&&i.restrictedModels.length>0&&(b.restrictedModels=i.restrictedModels),i.enableClientRestriction&&i.allowedClients.length>0&&(b.allowedClients=i.allowedClients);const o=await V.post("/admin/api-keys",b);o.success?(D("API Key 创建成功","success"),C("success",o.apiKey),C("close")):D(o.message||"创建失败","error")}catch{D("创建失败","error")}finally{L.value=!1}};return(b,o)=>(r(),q(Z,{to:"body"},[t("div",ht,[t("div",Tt,[t("div",Et,[o[25]||(o[25]=t("div",{class:"flex items-center gap-3"},[t("div",{class:"w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl flex items-center justify-center"},[t("i",{class:"fas fa-key text-white"})]),t("h3",{class:"text-xl font-bold text-gray-900"},"创建新的 API Key")],-1)),t("button",{onClick:o[0]||(o[0]=u=>b.$emit("close")),class:"text-gray-400 hover:text-gray-600 transition-colors"},o[24]||(o[24]=[t("i",{class:"fas fa-times text-xl"},null,-1)]))]),t("form",{onSubmit:B(m,["prevent"]),class:"space-y-6 modal-scroll-content custom-scrollbar flex-1"},[t("div",null,[o[26]||(o[26]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"名称",-1)),w(t("input",{"onUpdate:modelValue":o[1]||(o[1]=u=>i.name=u),type:"text",required:"",class:"form-input w-full",placeholder:"为您的 API Key 取一个名称"},null,512),[[M,i.name]])]),t("div",Pt,[o[33]||(o[33]=t("div",{class:"flex items-start gap-3 mb-3"},[t("div",{class:"w-8 h-8 bg-blue-500 rounded-lg flex items-center justify-center flex-shrink-0"},[t("i",{class:"fas fa-tachometer-alt text-white text-sm"})]),t("div",{class:"flex-1"},[t("h4",{class:"font-semibold text-gray-800 mb-1"},"速率限制设置 (可选)"),t("p",{class:"text-sm text-gray-600"},"控制 API Key 的使用频率和资源消耗")])],-1)),t("div",null,[o[27]||(o[27]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"时间窗口 (分钟)",-1)),w(t("input",{"onUpdate:modelValue":o[2]||(o[2]=u=>i.rateLimitWindow=u),type:"number",min:"1",placeholder:"留空表示无限制",class:"form-input w-full"},null,512),[[M,i.rateLimitWindow]]),o[28]||(o[28]=t("p",{class:"text-xs text-gray-500 mt-2"},"设置一个时间段(以分钟为单位),用于计算速率限制",-1))]),t("div",null,[o[29]||(o[29]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"时间窗口内的请求次数限制",-1)),w(t("input",{"onUpdate:modelValue":o[3]||(o[3]=u=>i.rateLimitRequests=u),type:"number",min:"1",placeholder:"留空表示无限制",class:"form-input w-full"},null,512),[[M,i.rateLimitRequests]]),o[30]||(o[30]=t("p",{class:"text-xs text-gray-500 mt-2"},"在时间窗口内允许的最大请求次数(需要先设置时间窗口)",-1))]),t("div",null,[o[31]||(o[31]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"时间窗口内的 Token 使用量限制",-1)),w(t("input",{"onUpdate:modelValue":o[4]||(o[4]=u=>i.tokenLimit=u),type:"number",placeholder:"留空表示无限制",class:"form-input w-full"},null,512),[[M,i.tokenLimit]]),o[32]||(o[32]=t("p",{class:"text-xs text-gray-500 mt-2"},"在时间窗口内允许消耗的最大 Token 数量(需要先设置时间窗口)",-1))]),o[34]||(o[34]=t("div",{class:"bg-blue-100 rounded-lg p-3 mt-3"},[t("h5",{class:"text-sm font-semibold text-blue-800 mb-2"},"💡 使用示例"),t("div",{class:"text-xs text-blue-700 space-y-1"},[t("p",null,[t("strong",null,"示例1:"),f(" 时间窗口=60请求次数限制=1000")]),t("p",{class:"ml-4"},"→ 每60分钟内最多1000次请求"),t("p",{class:"mt-2"},[t("strong",null,"示例2:"),f(" 时间窗口=1Token限制=10000")]),t("p",{class:"ml-4"},"→ 每分钟最多消耗10,000个Token"),t("p",{class:"mt-2"},[t("strong",null,"示例3:"),f(" 时间窗口=30请求次数限制=50Token限制=100000")]),t("p",{class:"ml-4"},"→ 每30分钟内最多50次请求且总Token不超过100,000")])],-1))]),t("div",null,[o[36]||(o[36]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"每日费用限制 (美元)",-1)),t("div",jt,[t("div",Vt,[t("button",{type:"button",onClick:o[5]||(o[5]=u=>i.dailyCostLimit="50"),class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium"},"$50"),t("button",{type:"button",onClick:o[6]||(o[6]=u=>i.dailyCostLimit="100"),class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium"},"$100"),t("button",{type:"button",onClick:o[7]||(o[7]=u=>i.dailyCostLimit="200"),class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium"},"$200"),t("button",{type:"button",onClick:o[8]||(o[8]=u=>i.dailyCostLimit=""),class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium"},"自定义")]),w(t("input",{"onUpdate:modelValue":o[9]||(o[9]=u=>i.dailyCostLimit=u),type:"number",min:"0",step:"0.01",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[M,i.dailyCostLimit]]),o[35]||(o[35]=t("p",{class:"text-xs text-gray-500"},"设置此 API Key 每日的费用限制超过限制将拒绝请求0 或留空表示无限制",-1))])]),t("div",null,[o[37]||(o[37]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"并发限制 (可选)",-1)),w(t("input",{"onUpdate:modelValue":o[10]||(o[10]=u=>i.concurrencyLimit=u),type:"number",min:"0",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[M,i.concurrencyLimit]]),o[38]||(o[38]=t("p",{class:"text-xs text-gray-500 mt-2"},"设置此 API Key 可同时处理的最大请求数0 或留空表示无限制",-1))]),t("div",null,[o[39]||(o[39]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"备注 (可选)",-1)),w(t("textarea",{"onUpdate:modelValue":o[11]||(o[11]=u=>i.description=u),rows:"3",class:"form-input w-full resize-none",placeholder:"描述此 API Key 的用途..."},null,512),[[M,i.description]])]),t("div",null,[o[41]||(o[41]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"有效期限",-1)),w(t("select",{"onUpdate:modelValue":o[12]||(o[12]=u=>i.expireDuration=u),onChange:$,class:"form-input w-full"},o[40]||(o[40]=[t("option",{value:""},"永不过期",-1),t("option",{value:"1d"},"1 天",-1),t("option",{value:"7d"},"7 天",-1),t("option",{value:"30d"},"30 天",-1),t("option",{value:"90d"},"90 天",-1),t("option",{value:"180d"},"180 天",-1),t("option",{value:"365d"},"365 天",-1),t("option",{value:"custom"},"自定义日期",-1)]),544),[[O,i.expireDuration]]),i.expireDuration==="custom"?(r(),d("div",_t,[w(t("input",{"onUpdate:modelValue":o[13]||(o[13]=u=>i.customExpireDate=u),type:"datetime-local",class:"form-input w-full",min:n.value,onChange:v},null,40,Ut),[[M,i.customExpireDate]])])):A("",!0),i.expiresAt?(r(),d("p",qt," 将于 "+p(P(i.expiresAt))+" 过期 ",1)):A("",!0)]),t("div",null,[o[45]||(o[45]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"服务权限",-1)),t("div",Ot,[t("label",Ft,[w(t("input",{type:"radio","onUpdate:modelValue":o[14]||(o[14]=u=>i.permissions=u),value:"all",class:"mr-2"},null,512),[[z,i.permissions]]),o[42]||(o[42]=t("span",{class:"text-sm text-gray-700"},"全部服务",-1))]),t("label",Wt,[w(t("input",{type:"radio","onUpdate:modelValue":o[15]||(o[15]=u=>i.permissions=u),value:"claude",class:"mr-2"},null,512),[[z,i.permissions]]),o[43]||(o[43]=t("span",{class:"text-sm text-gray-700"},"仅 Claude",-1))]),t("label",zt,[w(t("input",{type:"radio","onUpdate:modelValue":o[16]||(o[16]=u=>i.permissions=u),value:"gemini",class:"mr-2"},null,512),[[z,i.permissions]]),o[44]||(o[44]=t("span",{class:"text-sm text-gray-700"},"仅 Gemini",-1))])]),o[46]||(o[46]=t("p",{class:"text-xs text-gray-500 mt-2"},"控制此 API Key 可以访问哪些服务",-1))]),t("div",null,[o[51]||(o[51]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"专属账号绑定 (可选)",-1)),t("div",Yt,[t("div",null,[o[48]||(o[48]=t("label",{class:"block text-sm font-medium text-gray-600 mb-1"},"Claude 专属账号",-1)),w(t("select",{"onUpdate:modelValue":o[17]||(o[17]=u=>i.claudeAccountId=u),class:"form-input w-full",disabled:i.permissions==="gemini"},[o[47]||(o[47]=t("option",{value:""},"使用共享账号池",-1)),(r(!0),d(h,null,E(k.accounts.claude.filter(u=>u.isDedicated),u=>(r(),d("option",{key:u.id,value:u.id},p(u.name)+" ("+p(u.status==="active"?"正常":"异常")+") ",9,Ht))),128))],8,Nt),[[O,i.claudeAccountId]])]),t("div",null,[o[50]||(o[50]=t("label",{class:"block text-sm font-medium text-gray-600 mb-1"},"Gemini 专属账号",-1)),w(t("select",{"onUpdate:modelValue":o[18]||(o[18]=u=>i.geminiAccountId=u),class:"form-input w-full",disabled:i.permissions==="claude"},[o[49]||(o[49]=t("option",{value:""},"使用共享账号池",-1)),(r(!0),d(h,null,E(k.accounts.gemini.filter(u=>u.isDedicated),u=>(r(),d("option",{key:u.id,value:u.id},p(u.name)+" ("+p(u.status==="active"?"正常":"异常")+") ",9,Gt))),128))],8,Bt),[[O,i.geminiAccountId]])])]),o[52]||(o[52]=t("p",{class:"text-xs text-gray-500 mt-2"},"选择专属账号后此API Key将只使用该账号不选择则使用共享账号池",-1))]),t("div",null,[t("div",Xt,[w(t("input",{type:"checkbox","onUpdate:modelValue":o[19]||(o[19]=u=>i.enableModelRestriction=u),id:"enableModelRestriction",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[Y,i.enableModelRestriction]]),o[53]||(o[53]=t("label",{for:"enableModelRestriction",class:"ml-2 text-sm font-semibold text-gray-700 cursor-pointer"}," 启用模型限制 ",-1))]),i.enableModelRestriction?(r(),d("div",Qt,[t("div",null,[o[56]||(o[56]=t("label",{class:"block text-sm font-medium text-gray-600 mb-2"},"限制的模型列表",-1)),t("div",Jt,[(r(!0),d(h,null,E(i.restrictedModels,(u,j)=>(r(),d("span",{key:j,class:"inline-flex items-center px-3 py-1 rounded-full text-sm bg-red-100 text-red-800"},[f(p(u)+" ",1),t("button",{type:"button",onClick:N=>l(j),class:"ml-2 text-red-600 hover:text-red-800"},o[54]||(o[54]=[t("i",{class:"fas fa-times text-xs"},null,-1)]),8,Zt)]))),128)),i.restrictedModels.length===0?(r(),d("span",te," 暂无限制的模型 ")):A("",!0)]),t("div",ee,[w(t("input",{"onUpdate:modelValue":o[20]||(o[20]=u=>i.modelInput=u),onKeydown:pt(B(y,["prevent"]),["enter"]),type:"text",placeholder:"输入模型名称,按回车添加",class:"form-input flex-1"},null,40,se),[[M,i.modelInput]]),t("button",{type:"button",onClick:y,class:"px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors"},o[55]||(o[55]=[t("i",{class:"fas fa-plus"},null,-1)]))]),o[57]||(o[57]=t("p",{class:"text-xs text-gray-500 mt-2"},"设置此API Key无法访问的模型例如claude-opus-4-20250514",-1))])])):A("",!0)]),t("div",null,[t("div",le,[w(t("input",{type:"checkbox","onUpdate:modelValue":o[21]||(o[21]=u=>i.enableClientRestriction=u),id:"enableClientRestriction",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[Y,i.enableClientRestriction]]),o[58]||(o[58]=t("label",{for:"enableClientRestriction",class:"ml-2 text-sm font-semibold text-gray-700 cursor-pointer"}," 启用客户端限制 ",-1))]),i.enableClientRestriction?(r(),d("div",oe,[t("div",null,[o[59]||(o[59]=t("label",{class:"block text-sm font-medium text-gray-600 mb-2"},"允许的客户端",-1)),o[60]||(o[60]=t("p",{class:"text-xs text-gray-500 mb-3"},"勾选允许使用此API Key的客户端",-1)),t("div",ie,[(r(!0),d(h,null,E(x.value,u=>(r(),d("div",{key:u.id,class:"flex items-start"},[w(t("input",{type:"checkbox",id:`client_${u.id}`,value:u.id,"onUpdate:modelValue":o[22]||(o[22]=j=>i.allowedClients=j),class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 mt-0.5"},null,8,ne),[[Y,i.allowedClients]]),t("label",{for:`client_${u.id}`,class:"ml-2 flex-1 cursor-pointer"},[t("span",re,p(u.name),1),t("span",de,p(u.description),1)],8,ae)]))),128))])])])):A("",!0)]),t("div",ue,[t("button",{type:"button",onClick:o[23]||(o[23]=u=>b.$emit("close")),class:"flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors"}," 取消 "),t("button",{type:"submit",disabled:L.value||!i.name,class:"btn btn-primary flex-1 py-3 px-6 font-semibold"},[L.value?(r(),d("div",pe)):(r(),d("i",ce)),f(" "+p(L.value?"创建中...":"创建"),1)],8,me)])],32)])])]))}},ye=G(xe,[["__scopeId","data-v-d945af7f"]]),fe={class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},ge={class:"modal-content w-full max-w-md p-8 mx-auto max-h-[90vh] flex flex-col"},be={class:"flex items-center justify-between mb-6"},ve=["value"],we={class:"bg-blue-50 border border-blue-200 rounded-lg p-4 space-y-4"},$e={class:"space-y-3"},Ce={class:"flex gap-2"},Ae={class:"flex gap-4"},ke={class:"flex items-center cursor-pointer"},Ke={class:"flex items-center cursor-pointer"},Le={class:"flex items-center cursor-pointer"},De={class:"grid grid-cols-1 gap-3"},Ie=["disabled"],Me=["value"],Re=["disabled"],Se=["value"],he={class:"flex items-center mb-3"},Te={key:0,class:"space-y-3"},Ee={class:"flex flex-wrap gap-2 mb-3 min-h-[32px] p-2 bg-gray-50 rounded-lg border border-gray-200"},Pe=["onClick"],je={key:0,class:"text-gray-400 text-sm"},Ve={class:"flex gap-2"},_e=["onKeydown"],Ue={class:"flex items-center mb-3"},qe={key:0,class:"space-y-3"},Oe={class:"space-y-2"},Fe=["id","value"],We=["for"],ze={class:"text-sm font-medium text-gray-700"},Ye={class:"text-xs text-gray-500 block"},Ne={class:"flex gap-3 pt-4"},He=["disabled"],Be={key:0,class:"loading-spinner mr-2"},Ge={key:1,class:"fas fa-save mr-2"},Xe={__name:"EditApiKeyModal",props:{apiKey:{type:Object,required:!0},accounts:{type:Object,default:()=>({claude:[],gemini:[]})}},emits:["close","success"],setup(k,{emit:_}){const C=k,I=_;it();const L=nt(),x=K(!1),i=K([]),n=lt({name:"",tokenLimit:"",rateLimitWindow:"",rateLimitRequests:"",concurrencyLimit:"",dailyCostLimit:"",permissions:"all",claudeAccountId:"",geminiAccountId:"",enableModelRestriction:!1,restrictedModels:[],modelInput:"",enableClientRestriction:!1,allowedClients:[]}),$=()=>{n.modelInput&&!n.restrictedModels.includes(n.modelInput)&&(n.restrictedModels.push(n.modelInput),n.modelInput="")},v=y=>{n.restrictedModels.splice(y,1)},P=async()=>{x.value=!0;try{const y={tokenLimit:n.tokenLimit!==""&&n.tokenLimit!==null?parseInt(n.tokenLimit):0,rateLimitWindow:n.rateLimitWindow!==""&&n.rateLimitWindow!==null?parseInt(n.rateLimitWindow):0,rateLimitRequests:n.rateLimitRequests!==""&&n.rateLimitRequests!==null?parseInt(n.rateLimitRequests):0,concurrencyLimit:n.concurrencyLimit!==""&&n.concurrencyLimit!==null?parseInt(n.concurrencyLimit):0,dailyCostLimit:n.dailyCostLimit!==""&&n.dailyCostLimit!==null?parseFloat(n.dailyCostLimit):0,permissions:n.permissions,claudeAccountId:n.claudeAccountId||null,geminiAccountId:n.geminiAccountId||null};n.enableModelRestriction&&n.restrictedModels.length>0?y.restrictedModels=n.restrictedModels:y.restrictedModels=[],n.enableClientRestriction&&n.allowedClients.length>0?y.allowedClients=n.allowedClients:y.allowedClients=[];const l=await V.put(`/admin/api-keys/${C.apiKey.id}`,y);l.success?(I("success"),I("close")):D(l.message||"更新失败","error")}catch{D("更新失败","error")}finally{x.value=!1}};return ot(async()=>{i.value=await L.loadSupportedClients(),n.name=C.apiKey.name,n.tokenLimit=C.apiKey.tokenLimit||"",n.rateLimitWindow=C.apiKey.rateLimitWindow||"",n.rateLimitRequests=C.apiKey.rateLimitRequests||"",n.concurrencyLimit=C.apiKey.concurrencyLimit||"",n.dailyCostLimit=C.apiKey.dailyCostLimit||"",n.permissions=C.apiKey.permissions||"all",n.claudeAccountId=C.apiKey.claudeAccountId||"",n.geminiAccountId=C.apiKey.geminiAccountId||"",n.restrictedModels=C.apiKey.restrictedModels||[],n.allowedClients=C.apiKey.allowedClients||[],n.enableModelRestriction=n.restrictedModels.length>0,n.enableClientRestriction=n.allowedClients.length>0}),(y,l)=>(r(),q(Z,{to:"body"},[t("div",fe,[t("div",ge,[t("div",be,[l[21]||(l[21]=t("div",{class:"flex items-center gap-3"},[t("div",{class:"w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl flex items-center justify-center"},[t("i",{class:"fas fa-edit text-white"})]),t("h3",{class:"text-xl font-bold text-gray-900"},"编辑 API Key")],-1)),t("button",{onClick:l[0]||(l[0]=m=>y.$emit("close")),class:"text-gray-400 hover:text-gray-600 transition-colors"},l[20]||(l[20]=[t("i",{class:"fas fa-times text-xl"},null,-1)]))]),t("form",{onSubmit:B(P,["prevent"]),class:"space-y-6 modal-scroll-content custom-scrollbar flex-1"},[t("div",null,[l[22]||(l[22]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"名称",-1)),t("input",{value:n.name,type:"text",disabled:"",class:"form-input w-full bg-gray-100 cursor-not-allowed"},null,8,ve),l[23]||(l[23]=t("p",{class:"text-xs text-gray-500 mt-2"},"名称不可修改",-1))]),t("div",we,[l[30]||(l[30]=t("div",{class:"flex items-start gap-3 mb-3"},[t("div",{class:"w-8 h-8 bg-blue-500 rounded-lg flex items-center justify-center flex-shrink-0"},[t("i",{class:"fas fa-tachometer-alt text-white text-sm"})]),t("div",{class:"flex-1"},[t("h4",{class:"font-semibold text-gray-800 mb-1"},"速率限制设置"),t("p",{class:"text-sm text-gray-600"},"控制 API Key 的使用频率和资源消耗")])],-1)),t("div",null,[l[24]||(l[24]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"时间窗口 (分钟)",-1)),w(t("input",{"onUpdate:modelValue":l[1]||(l[1]=m=>n.rateLimitWindow=m),type:"number",min:"1",placeholder:"留空表示无限制",class:"form-input w-full"},null,512),[[M,n.rateLimitWindow]]),l[25]||(l[25]=t("p",{class:"text-xs text-gray-500 mt-2"},"设置一个时间段(以分钟为单位),用于计算速率限制",-1))]),t("div",null,[l[26]||(l[26]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"时间窗口内的请求次数限制",-1)),w(t("input",{"onUpdate:modelValue":l[2]||(l[2]=m=>n.rateLimitRequests=m),type:"number",min:"1",placeholder:"留空表示无限制",class:"form-input w-full"},null,512),[[M,n.rateLimitRequests]]),l[27]||(l[27]=t("p",{class:"text-xs text-gray-500 mt-2"},"在时间窗口内允许的最大请求次数(需要先设置时间窗口)",-1))]),t("div",null,[l[28]||(l[28]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"时间窗口内的 Token 使用量限制",-1)),w(t("input",{"onUpdate:modelValue":l[3]||(l[3]=m=>n.tokenLimit=m),type:"number",min:"0",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[M,n.tokenLimit]]),l[29]||(l[29]=t("p",{class:"text-xs text-gray-500 mt-2"},"在时间窗口内允许消耗的最大 Token 数量需要先设置时间窗口0 或留空表示无限制",-1))]),l[31]||(l[31]=t("div",{class:"bg-blue-100 rounded-lg p-3 mt-3"},[t("h5",{class:"text-sm font-semibold text-blue-800 mb-2"},"💡 使用示例"),t("div",{class:"text-xs text-blue-700 space-y-1"},[t("p",null,[t("strong",null,"示例1:"),f(" 时间窗口=60请求次数限制=100")]),t("p",{class:"ml-4"},"→ 每60分钟内最多允许100次请求"),t("p",{class:"mt-2"},[t("strong",null,"示例2:"),f(" 时间窗口=10Token限制=50000")]),t("p",{class:"ml-4"},"→ 每10分钟内最多消耗50,000个Token"),t("p",{class:"mt-2"},[t("strong",null,"示例3:"),f(" 时间窗口=30请求次数限制=50Token限制=100000")]),t("p",{class:"ml-4"},"→ 每30分钟内最多50次请求且总Token不超过100,000")])],-1))]),t("div",null,[l[33]||(l[33]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"每日费用限制 (美元)",-1)),t("div",$e,[t("div",Ce,[t("button",{type:"button",onClick:l[4]||(l[4]=m=>n.dailyCostLimit="50"),class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium"},"$50"),t("button",{type:"button",onClick:l[5]||(l[5]=m=>n.dailyCostLimit="100"),class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium"},"$100"),t("button",{type:"button",onClick:l[6]||(l[6]=m=>n.dailyCostLimit="200"),class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium"},"$200"),t("button",{type:"button",onClick:l[7]||(l[7]=m=>n.dailyCostLimit=""),class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium"},"自定义")]),w(t("input",{"onUpdate:modelValue":l[8]||(l[8]=m=>n.dailyCostLimit=m),type:"number",min:"0",step:"0.01",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[M,n.dailyCostLimit]]),l[32]||(l[32]=t("p",{class:"text-xs text-gray-500"},"设置此 API Key 每日的费用限制超过限制将拒绝请求0 或留空表示无限制",-1))])]),t("div",null,[l[34]||(l[34]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"并发限制",-1)),w(t("input",{"onUpdate:modelValue":l[9]||(l[9]=m=>n.concurrencyLimit=m),type:"number",min:"0",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[M,n.concurrencyLimit]]),l[35]||(l[35]=t("p",{class:"text-xs text-gray-500 mt-2"},"设置此 API Key 可同时处理的最大请求数",-1))]),t("div",null,[l[39]||(l[39]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"服务权限",-1)),t("div",Ae,[t("label",ke,[w(t("input",{type:"radio","onUpdate:modelValue":l[10]||(l[10]=m=>n.permissions=m),value:"all",class:"mr-2"},null,512),[[z,n.permissions]]),l[36]||(l[36]=t("span",{class:"text-sm text-gray-700"},"全部服务",-1))]),t("label",Ke,[w(t("input",{type:"radio","onUpdate:modelValue":l[11]||(l[11]=m=>n.permissions=m),value:"claude",class:"mr-2"},null,512),[[z,n.permissions]]),l[37]||(l[37]=t("span",{class:"text-sm text-gray-700"},"仅 Claude",-1))]),t("label",Le,[w(t("input",{type:"radio","onUpdate:modelValue":l[12]||(l[12]=m=>n.permissions=m),value:"gemini",class:"mr-2"},null,512),[[z,n.permissions]]),l[38]||(l[38]=t("span",{class:"text-sm text-gray-700"},"仅 Gemini",-1))])]),l[40]||(l[40]=t("p",{class:"text-xs text-gray-500 mt-2"},"控制此 API Key 可以访问哪些服务",-1))]),t("div",null,[l[45]||(l[45]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"专属账号绑定",-1)),t("div",De,[t("div",null,[l[42]||(l[42]=t("label",{class:"block text-sm font-medium text-gray-600 mb-1"},"Claude 专属账号",-1)),w(t("select",{"onUpdate:modelValue":l[13]||(l[13]=m=>n.claudeAccountId=m),class:"form-input w-full",disabled:n.permissions==="gemini"},[l[41]||(l[41]=t("option",{value:""},"使用共享账号池",-1)),(r(!0),d(h,null,E(k.accounts.claude,m=>(r(),d("option",{key:m.id,value:m.id},p(m.name)+" ("+p(m.status==="active"?"正常":"异常")+") ",9,Me))),128))],8,Ie),[[O,n.claudeAccountId]])]),t("div",null,[l[44]||(l[44]=t("label",{class:"block text-sm font-medium text-gray-600 mb-1"},"Gemini 专属账号",-1)),w(t("select",{"onUpdate:modelValue":l[14]||(l[14]=m=>n.geminiAccountId=m),class:"form-input w-full",disabled:n.permissions==="claude"},[l[43]||(l[43]=t("option",{value:""},"使用共享账号池",-1)),(r(!0),d(h,null,E(k.accounts.gemini,m=>(r(),d("option",{key:m.id,value:m.id},p(m.name)+" ("+p(m.status==="active"?"正常":"异常")+") ",9,Se))),128))],8,Re),[[O,n.geminiAccountId]])])]),l[46]||(l[46]=t("p",{class:"text-xs text-gray-500 mt-2"},"修改绑定账号将影响此API Key的请求路由",-1))]),t("div",null,[t("div",he,[w(t("input",{type:"checkbox","onUpdate:modelValue":l[15]||(l[15]=m=>n.enableModelRestriction=m),id:"editEnableModelRestriction",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[Y,n.enableModelRestriction]]),l[47]||(l[47]=t("label",{for:"editEnableModelRestriction",class:"ml-2 text-sm font-semibold text-gray-700 cursor-pointer"}," 启用模型限制 ",-1))]),n.enableModelRestriction?(r(),d("div",Te,[t("div",null,[l[50]||(l[50]=t("label",{class:"block text-sm font-medium text-gray-600 mb-2"},"限制的模型列表",-1)),t("div",Ee,[(r(!0),d(h,null,E(n.restrictedModels,(m,b)=>(r(),d("span",{key:b,class:"inline-flex items-center px-3 py-1 rounded-full text-sm bg-red-100 text-red-800"},[f(p(m)+" ",1),t("button",{type:"button",onClick:o=>v(b),class:"ml-2 text-red-600 hover:text-red-800"},l[48]||(l[48]=[t("i",{class:"fas fa-times text-xs"},null,-1)]),8,Pe)]))),128)),n.restrictedModels.length===0?(r(),d("span",je," 暂无限制的模型 ")):A("",!0)]),t("div",Ve,[w(t("input",{"onUpdate:modelValue":l[16]||(l[16]=m=>n.modelInput=m),onKeydown:pt(B($,["prevent"]),["enter"]),type:"text",placeholder:"输入模型名称,按回车添加",class:"form-input flex-1"},null,40,_e),[[M,n.modelInput]]),t("button",{type:"button",onClick:$,class:"px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors"},l[49]||(l[49]=[t("i",{class:"fas fa-plus"},null,-1)]))]),l[51]||(l[51]=t("p",{class:"text-xs text-gray-500 mt-2"},"设置此API Key无法访问的模型例如claude-opus-4-20250514",-1))])])):A("",!0)]),t("div",null,[t("div",Ue,[w(t("input",{type:"checkbox","onUpdate:modelValue":l[17]||(l[17]=m=>n.enableClientRestriction=m),id:"editEnableClientRestriction",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[Y,n.enableClientRestriction]]),l[52]||(l[52]=t("label",{for:"editEnableClientRestriction",class:"ml-2 text-sm font-semibold text-gray-700 cursor-pointer"}," 启用客户端限制 ",-1))]),n.enableClientRestriction?(r(),d("div",qe,[t("div",null,[l[53]||(l[53]=t("label",{class:"block text-sm font-medium text-gray-600 mb-2"},"允许的客户端",-1)),l[54]||(l[54]=t("p",{class:"text-xs text-gray-500 mb-3"},"勾选允许使用此API Key的客户端",-1)),t("div",Oe,[(r(!0),d(h,null,E(i.value,m=>(r(),d("div",{key:m.id,class:"flex items-start"},[w(t("input",{type:"checkbox",id:`edit_client_${m.id}`,value:m.id,"onUpdate:modelValue":l[18]||(l[18]=b=>n.allowedClients=b),class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 mt-0.5"},null,8,Fe),[[Y,n.allowedClients]]),t("label",{for:`edit_client_${m.id}`,class:"ml-2 flex-1 cursor-pointer"},[t("span",ze,p(m.name),1),t("span",Ye,p(m.description),1)],8,We)]))),128))])])])):A("",!0)]),t("div",Ne,[t("button",{type:"button",onClick:l[19]||(l[19]=m=>y.$emit("close")),class:"flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors"}," 取消 "),t("button",{type:"submit",disabled:x.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold"},[x.value?(r(),d("div",Be)):(r(),d("i",Ge)),f(" "+p(x.value?"保存中...":"保存修改"),1)],8,He)])],32)])])]))}},Qe=G(Xe,[["__scopeId","data-v-cdbb188f"]]),Je={class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},Ze={class:"modal-content w-full max-w-md p-8 mx-auto max-h-[90vh] flex flex-col"},ts={class:"flex items-center justify-between mb-6"},es={class:"space-y-6 modal-scroll-content custom-scrollbar flex-1"},ss={class:"bg-blue-50 border border-blue-200 rounded-lg p-4"},ls={class:"flex items-start gap-3"},os={class:"text-sm text-gray-700"},is={class:"text-xs text-gray-600 mt-1"},ns={key:0,class:"mt-3"},as=["min"],rs={key:1,class:"text-xs text-gray-500 mt-2"},ds={class:"flex gap-3 pt-4"},us=["disabled"],ms={key:0,class:"loading-spinner mr-2"},ps={key:1,class:"fas fa-clock mr-2"},cs={__name:"RenewApiKeyModal",props:{apiKey:{type:Object,required:!0}},emits:["close","success"],setup(k,{emit:_}){const C=k,I=_;it();const L=K(!1),x=lt({renewDuration:"30d",customExpireDate:"",newExpiresAt:null}),i=J(()=>{const y=new Date;return C.apiKey.expiresAt&&new Date(C.apiKey.expiresAt)>y?new Date(C.apiKey.expiresAt).toISOString().slice(0,16):(y.setMinutes(y.getMinutes()+1),y.toISOString().slice(0,16))}),n=y=>new Date(y).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}),$=()=>{if(!x.renewDuration){x.newExpiresAt=null;return}if(x.renewDuration==="permanent"){x.newExpiresAt=null;return}if(x.renewDuration==="custom")return;const y=C.apiKey.expiresAt&&new Date(C.apiKey.expiresAt)>new Date?new Date(C.apiKey.expiresAt):new Date,m=x.renewDuration.match(/(\d+)([dhmy])/);if(m){const[,b,o]=m,u=parseInt(b);switch(o){case"d":y.setDate(y.getDate()+u);break;case"h":y.setHours(y.getHours()+u);break;case"m":y.setMonth(y.getMonth()+u);break;case"y":y.setFullYear(y.getFullYear()+u);break}x.newExpiresAt=y.toISOString()}},v=()=>{x.customExpireDate&&(x.newExpiresAt=new Date(x.customExpireDate).toISOString())},P=async()=>{L.value=!0;try{const y={expiresAt:x.renewDuration==="permanent"?null:x.newExpiresAt},l=await V.put(`/admin/api-keys/${C.apiKey.id}/renew`,y);l.success?(D("API Key 续期成功","success"),I("success"),I("close")):D(l.message||"续期失败","error")}catch{D("续期失败","error")}finally{L.value=!1}};return $(),(y,l)=>(r(),q(Z,{to:"body"},[t("div",Je,[t("div",Ze,[t("div",ts,[l[5]||(l[5]=t("div",{class:"flex items-center gap-3"},[t("div",{class:"w-10 h-10 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center"},[t("i",{class:"fas fa-clock text-white"})]),t("h3",{class:"text-xl font-bold text-gray-900"},"续期 API Key")],-1)),t("button",{onClick:l[0]||(l[0]=m=>y.$emit("close")),class:"text-gray-400 hover:text-gray-600 transition-colors"},l[4]||(l[4]=[t("i",{class:"fas fa-times text-xl"},null,-1)]))]),t("div",es,[t("div",ss,[t("div",ls,[l[7]||(l[7]=t("div",{class:"w-8 h-8 bg-blue-500 rounded-lg flex items-center justify-center flex-shrink-0"},[t("i",{class:"fas fa-info text-white text-sm"})],-1)),t("div",null,[l[6]||(l[6]=t("h4",{class:"font-semibold text-gray-800 mb-1"},"API Key 信息",-1)),t("p",os,p(k.apiKey.name),1),t("p",is," 当前过期时间:"+p(k.apiKey.expiresAt?n(k.apiKey.expiresAt):"永不过期"),1)])])]),t("div",null,[l[9]||(l[9]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"续期时长",-1)),w(t("select",{"onUpdate:modelValue":l[1]||(l[1]=m=>x.renewDuration=m),onChange:$,class:"form-input w-full"},l[8]||(l[8]=[t("option",{value:"7d"},"延长 7 天",-1),t("option",{value:"30d"},"延长 30 天",-1),t("option",{value:"90d"},"延长 90 天",-1),t("option",{value:"180d"},"延长 180 天",-1),t("option",{value:"365d"},"延长 365 天",-1),t("option",{value:"custom"},"自定义日期",-1),t("option",{value:"permanent"},"设为永不过期",-1)]),544),[[O,x.renewDuration]]),x.renewDuration==="custom"?(r(),d("div",ns,[w(t("input",{"onUpdate:modelValue":l[2]||(l[2]=m=>x.customExpireDate=m),type:"datetime-local",class:"form-input w-full",min:i.value,onChange:v},null,40,as),[[M,x.customExpireDate]])])):A("",!0),x.newExpiresAt?(r(),d("p",rs," 新的过期时间:"+p(n(x.newExpiresAt)),1)):A("",!0)])]),t("div",ds,[t("button",{type:"button",onClick:l[3]||(l[3]=m=>y.$emit("close")),class:"flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors"}," 取消 "),t("button",{type:"button",onClick:P,disabled:L.value||!x.renewDuration,class:"btn btn-primary flex-1 py-3 px-6 font-semibold"},[L.value?(r(),d("div",ms)):(r(),d("i",ps)),f(" "+p(L.value?"续期中...":"确认续期"),1)],8,us)])])])]))}},xs=G(cs,[["__scopeId","data-v-5486ec2f"]]),ys={class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},fs={class:"modal-content w-full max-w-lg p-8 mx-auto"},gs={class:"flex items-center justify-between mb-6"},bs={class:"space-y-4 mb-6"},vs={class:"text-gray-900"},ws={key:0},$s={class:"text-gray-600 text-sm"},Cs={class:"relative"},As=["type","value"],ks={class:"absolute right-1 top-1 flex gap-1"},Ks=["title"],Ls={class:"bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6"},Ds={class:"text-sm text-gray-700 space-y-2"},Is={class:"block bg-white rounded px-3 py-2 text-xs"},Ms={class:"bg-white rounded px-3 py-2 text-xs overflow-x-auto"},Rs={class:"flex justify-end"},Ss={__name:"NewApiKeyModal",props:{apiKey:{type:Object,required:!0}},emits:["close"],setup(k,{emit:_}){const C=k,I=K(!1),L=K(!1),x=J(()=>`${window.location.protocol}//${window.location.host}/api/`),i=()=>{I.value=!I.value},n=async()=>{try{await navigator.clipboard.writeText(C.apiKey.key),L.value=!0,D("API Key 已复制到剪贴板","success"),setTimeout(()=>{L.value=!1},3e3)}catch{D("复制失败,请手动复制","error")}};return($,v)=>(r(),q(Z,{to:"body"},[t("div",ys,[t("div",fs,[t("div",gs,[v[3]||(v[3]=t("div",{class:"flex items-center gap-3"},[t("div",{class:"w-10 h-10 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center"},[t("i",{class:"fas fa-check text-white"})]),t("h3",{class:"text-xl font-bold text-gray-900"},"API Key 创建成功")],-1)),t("button",{onClick:v[0]||(v[0]=P=>$.$emit("close")),class:"text-gray-400 hover:text-gray-600 transition-colors"},v[2]||(v[2]=[t("i",{class:"fas fa-times text-xl"},null,-1)]))]),v[11]||(v[11]=t("div",{class:"bg-green-50 border border-green-200 rounded-lg p-4 mb-6"},[t("div",{class:"flex items-start gap-3"},[t("div",{class:"w-8 h-8 bg-green-500 rounded-lg flex items-center justify-center flex-shrink-0"},[t("i",{class:"fas fa-shield-alt text-white text-sm"})]),t("div",null,[t("h4",{class:"font-semibold text-gray-800 mb-1"},"请妥善保管您的 API Key"),t("p",{class:"text-sm text-gray-600"},"API Key 只会显示一次,关闭此窗口后将无法再次查看完整密钥。请立即复制并保存到安全的地方。")])])],-1)),t("div",bs,[t("div",null,[v[4]||(v[4]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"名称",-1)),t("p",vs,p(k.apiKey.name),1)]),k.apiKey.description?(r(),d("div",ws,[v[5]||(v[5]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"描述",-1)),t("p",$s,p(k.apiKey.description),1)])):A("",!0),t("div",null,[v[7]||(v[7]=t("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"API Key",-1)),t("div",Cs,[t("input",{type:I.value?"text":"password",value:k.apiKey.key,readonly:"",class:"form-input w-full pr-24 font-mono text-sm bg-gray-50"},null,8,As),t("div",ks,[t("button",{onClick:i,type:"button",class:"px-3 py-1.5 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm transition-colors",title:I.value?"隐藏":"显示"},[t("i",{class:S(I.value?"fas fa-eye-slash":"fas fa-eye")},null,2)],8,Ks),t("button",{onClick:n,type:"button",class:"px-3 py-1.5 bg-blue-100 hover:bg-blue-200 text-blue-700 rounded-lg text-sm transition-colors",title:"复制"},[v[6]||(v[6]=t("i",{class:"fas fa-copy"},null,-1)),f(" "+p(L.value?"已复制":"复制"),1)])])])])]),t("div",Ls,[v[10]||(v[10]=t("h4",{class:"font-semibold text-gray-800 mb-2"},[t("i",{class:"fas fa-info-circle mr-2 text-blue-500"}),f("使用说明 ")],-1)),t("div",Ds,[v[8]||(v[8]=t("p",null,"1. 在 HTTP 请求头中添加:",-1)),t("code",Is,"Authorization: Bearer "+p(k.apiKey.key),1),v[9]||(v[9]=t("p",{class:"pt-2"},"2. 请求示例:",-1)),t("pre",Ms,"curl -X POST "+p(x.value)+`v1/messages \\
-H "Authorization: Bearer `+p(k.apiKey.key)+`" \\
-H "Content-Type: application/json" \\
-d '{"model": "claude-3-opus-20240229", "messages": [...]}'`,1)])]),t("div",Rs,[t("button",{onClick:v[1]||(v[1]=P=>$.$emit("close")),class:"btn btn-primary px-6 py-2.5"}," 我已保存 ")])])])]))}},hs=G(Ss,[["__scopeId","data-v-747f035b"]]),Ts={class:"tab-content"},Es={class:"card p-6"},Ps={class:"flex flex-col md:flex-row justify-between items-center gap-4 mb-6"},js={class:"flex items-center gap-3"},Vs={key:0,class:"text-center py-12"},_s={key:1,class:"text-center py-12"},Us={key:2,class:"table-container"},qs={class:"min-w-full"},Os={class:"bg-gray-50/80 backdrop-blur-sm"},Fs={key:1,class:"fas fa-sort ml-1 text-gray-400"},Ws={key:1,class:"fas fa-sort ml-1 text-gray-400"},zs={class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider"},Ys={key:1,class:"fas fa-sort ml-1 text-gray-400"},Ns={key:1,class:"fas fa-sort ml-1 text-gray-400"},Hs={key:1,class:"fas fa-sort ml-1 text-gray-400"},Bs={class:"divide-y divide-gray-200/50"},Gs={class:"table-row"},Xs={class:"px-6 py-4 whitespace-nowrap"},Qs={class:"flex items-center"},Js={class:"text-sm font-semibold text-gray-900"},Zs={class:"text-xs text-gray-500"},tl={class:"text-xs text-gray-500 mt-1"},el={key:0},sl={key:1},ll={class:"px-6 py-4 whitespace-nowrap"},ol={class:"text-sm font-mono text-gray-600 bg-gray-50 px-3 py-1 rounded-lg"},il={class:"px-6 py-4 whitespace-nowrap"},nl={class:"px-6 py-4"},al={class:"space-y-1"},rl={class:"flex justify-between text-sm"},dl={class:"font-medium text-gray-900"},ul={class:"flex justify-between text-sm"},ml={class:"font-medium text-gray-900"},pl={class:"flex justify-between text-sm"},cl={class:"font-medium text-green-600"},xl={key:0,class:"flex justify-between text-sm"},yl={class:"flex justify-between text-sm"},fl={class:"font-medium text-purple-600"},gl={class:"flex justify-between text-sm"},bl={key:0,class:"text-xs text-gray-500"},vl={key:1,class:"flex justify-between text-sm"},wl={class:"font-medium text-indigo-600"},$l={key:2,class:"flex justify-between text-sm"},Cl={class:"font-medium text-indigo-600"},Al={class:"flex justify-between text-xs text-gray-500"},kl={key:3,class:"flex justify-between text-xs text-orange-500"},Kl={class:"flex justify-between text-xs text-blue-600"},Ll={class:"pt-1 border-t border-gray-100"},Dl={class:"flex justify-between text-xs text-green-600"},Il={class:"pt-2"},Ml=["onClick"],Rl={class:"px-6 py-4 whitespace-nowrap text-sm text-gray-500"},Sl={class:"px-6 py-4 whitespace-nowrap text-sm"},hl={key:0},Tl={key:0,class:"text-red-600"},El={key:1,class:"text-orange-600"},Pl={key:2,class:"text-gray-600"},jl={key:1,class:"text-gray-400"},Vl={class:"px-6 py-4 whitespace-nowrap text-sm"},_l={class:"flex gap-2"},Ul=["onClick"],ql=["onClick"],Ol=["onClick"],Fl=["onClick"],Wl={key:0},zl={colspan:"7",class:"px-6 py-4 bg-gray-50"},Yl={key:0,class:"text-center py-4"},Nl={class:"space-y-4"},Hl={class:"flex items-center justify-between mb-4"},Bl={class:"flex items-center gap-2"},Gl={key:0,class:"text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded-full"},Xl={class:"flex gap-1 items-center"},Ql={class:"flex gap-1 bg-gray-100 rounded p-1"},Jl=["onClick"],Zl={key:0,class:"text-center py-8"},to={class:"flex items-center justify-center gap-2 mb-3"},eo=["onClick"],so={key:1,class:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"},lo={class:"flex justify-between items-start mb-3"},oo={class:"flex-1"},io={class:"text-sm font-semibold text-gray-800 block mb-1"},no={class:"text-xs text-gray-500 bg-blue-50 px-2 py-1 rounded-full"},ao={class:"space-y-2 mb-3"},ro={class:"flex justify-between items-center text-sm"},uo={class:"font-semibold text-gray-900"},mo={class:"flex justify-between items-center text-sm"},po={class:"font-semibold text-green-600"},co={class:"pt-2 mt-2 border-t border-gray-100"},xo={class:"flex justify-between items-center text-xs text-gray-500"},yo={class:"font-medium"},fo={class:"flex justify-between items-center text-xs text-gray-500"},go={class:"font-medium"},bo={key:0,class:"flex justify-between items-center text-xs text-purple-600"},vo={class:"font-medium"},wo={key:1,class:"flex justify-between items-center text-xs text-purple-600"},$o={class:"font-medium"},Co={class:"w-full bg-gray-200 rounded-full h-2 mt-3"},Ao={class:"text-right mt-1"},ko={class:"text-xs font-medium text-indigo-600"},Ko={key:2,class:"mt-4 p-3 bg-gradient-to-r from-indigo-50 to-purple-50 rounded-lg border border-indigo-100"},Lo={class:"flex items-center justify-between text-sm"},Do={class:"flex gap-4 text-xs"},Io={class:"text-gray-600"},Mo={class:"font-semibold text-gray-800"},Ro={class:"text-gray-600"},So={class:"font-semibold text-gray-800"},ho={__name:"ApiKeysView",setup(k){const _=nt(),C=K([]),I=K(!1),L=K("today"),x=K(""),i=K("asc"),n=K({}),$=K({}),v=K({}),P=K([new Date(2e3,1,1,0,0,0),new Date(2e3,2,1,23,59,59)]),y=K({claude:[],gemini:[]}),l=K(!1),m=K(!1),b=K(!1),o=K(!1),u=K(null),j=K(null),N=K(null),F=J(()=>x.value?[...C.value].sort((e,g)=>{let s=e[x.value],c=g[x.value];return x.value==="status"?(s=e.isActive?1:0,c=g.isActive?1:0):x.value==="cost"?(s=parseFloat(tt(e.usage).replace("$","")),c=parseFloat(tt(g.usage).replace("$",""))):(x.value==="createdAt"||x.value==="expiresAt")&&(s=s?new Date(s).getTime():0,c=c?new Date(c).getTime():0),s<c?i.value==="asc"?-1:1:s>c?i.value==="asc"?1:-1:0}):C.value),ct=async()=>{try{const[a,e]=await Promise.all([V.get("/admin/claude-accounts"),V.get("/admin/gemini-accounts")]);a.success&&(y.value.claude=a.data||[]),e.success&&(y.value.gemini=e.data||[])}catch(a){console.error("加载账户列表失败:",a)}},W=async()=>{I.value=!0;try{const a=await V.get(`/admin/api-keys?timeRange=${L.value}`);a.success&&(C.value=a.data||[])}catch{D("加载 API Keys 失败","error")}finally{I.value=!1}},H=a=>{x.value===a?i.value=i.value==="asc"?"desc":"asc":(x.value=a,i.value="asc")},R=a=>!a&&a!==0?"0":a.toLocaleString("zh-CN"),tt=a=>!a||!a.total?"$0.0000":`$${(a.total.cost||0).toFixed(4)}`,xt=a=>{if(!a)return"未知账户";const e=y.value.claude.find(s=>s.id===a);if(e)return e.name;const g=y.value.gemini.find(s=>s.id===a);return g?g.name:`账户-${a.substring(0,8)}`},et=a=>a?new Date(a)<new Date:!1,at=a=>!a||et(a)?!1:(new Date(a)-new Date)/(1e3*60*60*24)<=7,rt=a=>a?new Date(a).toLocaleDateString("zh-CN"):"",yt=async a=>{n.value[a]?n.value[a]=!1:(n.value[a]=!0,v.value[a]||ut(a),await X(a,!0))},X=async(a,e=!1)=>{if(!e&&$.value[a]&&$.value[a].length>0)return;const g=U(a);try{let s=`/admin/api-keys/${a}/model-stats`;const c=new URLSearchParams;if(g.customStart&&g.customEnd)c.append("startDate",g.customStart),c.append("endDate",g.customEnd),c.append("period","custom");else{const Q=g.preset==="today"?"daily":"monthly";c.append("period",Q)}s+="?"+c.toString();const T=await V.get(s);T.success&&($.value[a]=T.data||[])}catch{D("加载模型统计失败","error"),$.value[a]=[]}},dt=(a,e)=>{const g=e.reduce((s,c)=>s+(c.allTokens||0),0);return g===0?0:Math.round(a/g*100)},ft=a=>a.formatted&&a.formatted.total?a.formatted.total:a.cost!==void 0?`$${a.cost.toFixed(6)}`:"$0.000000",ut=a=>{const e=new Date,g=new Date(e);g.setDate(e.getDate()-6),v.value[a]={type:"preset",preset:"7days",customStart:g.toISOString().split("T")[0],customEnd:e.toISOString().split("T")[0],customRange:null,presetOptions:[{value:"today",label:"今日",days:1},{value:"7days",label:"7天",days:7},{value:"30days",label:"30天",days:30}]}},U=a=>(v.value[a]||ut(a),v.value[a]),mt=(a,e)=>{const g=U(e);g.type="preset",g.preset=a;const s=g.presetOptions.find(c=>c.value===a);if(s){const c=new Date,T=new Date(c);T.setDate(c.getDate()-(s.days-1)),g.customStart=T.toISOString().split("T")[0],g.customEnd=c.toISOString().split("T")[0];const Q=st=>st.getFullYear()+"-"+String(st.getMonth()+1).padStart(2,"0")+"-"+String(st.getDate()).padStart(2,"0")+" 00:00:00";g.customRange=[Q(T),Q(c)]}X(e,!0)},gt=(a,e)=>{const g=U(a);e&&e.length===2?(g.type="custom",g.preset="",g.customRange=e,g.customStart=e[0].split(" ")[0],g.customEnd=e[1].split(" ")[0],X(a,!0)):e===null&&mt("7days",a)},bt=a=>a>new Date,vt=a=>{const e=U(a);e.type="preset",e.preset="7days";const g=new Date,s=new Date(g);s.setDate(g.getDate()-6),e.customStart=s.toISOString().split("T")[0],e.customEnd=g.toISOString().split("T")[0],e.customRange=null,X(a,!0),D("已重置筛选条件并刷新数据","info")},wt=()=>{l.value=!0},$t=a=>{u.value=a,m.value=!0},Ct=a=>{j.value=a,b.value=!0},At=a=>{l.value=!1,N.value=a,o.value=!0,W()},kt=()=>{m.value=!1,D("API Key 更新成功","success"),W()},Kt=()=>{b.value=!1,D("API Key 续期成功","success"),W()},Lt=async a=>{if(confirm("确定要删除这个 API Key 吗?此操作不可恢复。"))try{const e=await V.delete(`/admin/api-keys/${a}`);e.success?(D("API Key 已删除","success"),W()):D(e.message||"删除失败","error")}catch{D("删除失败","error")}},Dt=a=>{const g=`${window.location.origin}/admin/api-stats?apiId=${a.id}`,s=document.createElement("textarea");s.value=g,s.style.position="fixed",s.style.opacity="0",s.style.left="-9999px",document.body.appendChild(s),s.select(),s.setSelectionRange(0,99999);try{document.execCommand("copy")?D("已复制统计页面链接","success"):(D("复制失败,请手动复制","error"),console.log("统计页面链接:",g))}catch(c){D("复制失败,请手动复制","error"),console.error("复制错误:",c),console.log("统计页面链接:",g)}finally{document.body.removeChild(s)}};return ot(async()=>{await Promise.all([_.loadSupportedClients(),ct(),W()])}),(a,e)=>{const g=It;return r(),d("div",Ts,[t("div",Es,[t("div",Ps,[e[13]||(e[13]=t("div",null,[t("h3",{class:"text-xl font-bold text-gray-900 mb-2"},"API Keys 管理"),t("p",{class:"text-gray-600"},"管理和监控您的 API 密钥")],-1)),t("div",js,[w(t("select",{"onUpdate:modelValue":e[0]||(e[0]=s=>L.value=s),onChange:e[1]||(e[1]=s=>W()),class:"form-input px-3 py-2 text-sm"},e[11]||(e[11]=[t("option",{value:"today"},"今日",-1),t("option",{value:"7days"},"最近7天",-1),t("option",{value:"monthly"},"本月",-1),t("option",{value:"all"},"全部时间",-1)]),544),[[O,L.value]]),t("button",{onClick:B(wt,["stop"]),class:"btn btn-primary px-6 py-3 flex items-center gap-2"},e[12]||(e[12]=[t("i",{class:"fas fa-plus"},null,-1),f("创建新 Key ",-1)]))])]),I.value?(r(),d("div",Vs,e[14]||(e[14]=[t("div",{class:"loading-spinner mx-auto mb-4"},null,-1),t("p",{class:"text-gray-500"},"正在加载 API Keys...",-1)]))):C.value.length===0?(r(),d("div",_s,e[15]||(e[15]=[t("div",{class:"w-16 h-16 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center"},[t("i",{class:"fas fa-key text-gray-400 text-xl"})],-1),t("p",{class:"text-gray-500 text-lg"},"暂无 API Keys",-1),t("p",{class:"text-gray-400 text-sm mt-2"},"点击上方按钮创建您的第一个 API Key",-1)]))):(r(),d("div",Us,[t("table",qs,[t("thead",Os,[t("tr",null,[t("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider cursor-pointer hover:bg-gray-100",onClick:e[2]||(e[2]=s=>H("name"))},[e[16]||(e[16]=f(" 名称 ",-1)),x.value==="name"?(r(),d("i",{key:0,class:S(["fas",i.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),d("i",Fs))]),e[23]||(e[23]=t("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider"},"API Key",-1)),t("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider cursor-pointer hover:bg-gray-100",onClick:e[3]||(e[3]=s=>H("status"))},[e[17]||(e[17]=f(" 状态 ",-1)),x.value==="status"?(r(),d("i",{key:0,class:S(["fas",i.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),d("i",Ws))]),t("th",zs,[e[20]||(e[20]=f(" 使用统计 ",-1)),t("span",{class:"cursor-pointer hover:bg-gray-100 px-2 py-1 rounded",onClick:e[4]||(e[4]=s=>H("cost"))},[e[18]||(e[18]=f(" (费用 ",-1)),x.value==="cost"?(r(),d("i",{key:0,class:S(["fas",i.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),d("i",Ys)),e[19]||(e[19]=f(") ",-1))])]),t("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider cursor-pointer hover:bg-gray-100",onClick:e[5]||(e[5]=s=>H("createdAt"))},[e[21]||(e[21]=f(" 创建时间 ",-1)),x.value==="createdAt"?(r(),d("i",{key:0,class:S(["fas",i.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),d("i",Ns))]),t("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider cursor-pointer hover:bg-gray-100",onClick:e[6]||(e[6]=s=>H("expiresAt"))},[e[22]||(e[22]=f(" 过期时间 ",-1)),x.value==="expiresAt"?(r(),d("i",{key:0,class:S(["fas",i.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),d("i",Hs))]),e[24]||(e[24]=t("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider"},"操作",-1))])]),t("tbody",Bs,[(r(!0),d(h,null,E(F.value,s=>(r(),d(h,{key:s.id},[t("tr",Gs,[t("td",Xs,[t("div",Qs,[e[27]||(e[27]=t("div",{class:"w-8 h-8 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg flex items-center justify-center mr-3"},[t("i",{class:"fas fa-key text-white text-xs"})],-1)),t("div",null,[t("div",Js,p(s.name),1),t("div",Zs,p(s.id),1),t("div",tl,[s.claudeAccountId?(r(),d("span",el,[e[25]||(e[25]=t("i",{class:"fas fa-link mr-1"},null,-1)),f(" 绑定: "+p(xt(s.claudeAccountId)),1)])):(r(),d("span",sl,e[26]||(e[26]=[t("i",{class:"fas fa-share-alt mr-1"},null,-1),f(" 使用共享池 ",-1)])))])])])]),t("td",ll,[t("div",ol,p((s.apiKey||"").substring(0,20))+"... ",1)]),t("td",il,[t("span",{class:S(["inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold",s.isActive?"bg-green-100 text-green-800":"bg-red-100 text-red-800"])},[t("div",{class:S(["w-2 h-2 rounded-full mr-2",s.isActive?"bg-green-500":"bg-red-500"])},null,2),f(" "+p(s.isActive?"活跃":"禁用"),1)],2)]),t("td",nl,[t("div",al,[t("div",rl,[e[28]||(e[28]=t("span",{class:"text-gray-600"},"请求数:",-1)),t("span",dl,p(R(s.usage&&s.usage.total&&s.usage.total.requests||0)),1)]),t("div",ul,[e[29]||(e[29]=t("span",{class:"text-gray-600"},"Token:",-1)),t("span",ml,p(R(s.usage&&s.usage.total&&s.usage.total.tokens||0)),1)]),t("div",pl,[e[30]||(e[30]=t("span",{class:"text-gray-600"},"费用:",-1)),t("span",cl,p(tt(s.usage)),1)]),s.dailyCostLimit>0?(r(),d("div",xl,[e[31]||(e[31]=t("span",{class:"text-gray-600"},"今日费用:",-1)),t("span",{class:S(["font-medium",(s.dailyCost||0)>=s.dailyCostLimit?"text-red-600":"text-blue-600"])}," $"+p((s.dailyCost||0).toFixed(2))+" / $"+p(s.dailyCostLimit.toFixed(2)),3)])):A("",!0),t("div",yl,[e[32]||(e[32]=t("span",{class:"text-gray-600"},"并发限制:",-1)),t("span",fl,p(s.concurrencyLimit>0?s.concurrencyLimit:"无限制"),1)]),t("div",gl,[e[33]||(e[33]=t("span",{class:"text-gray-600"},"当前并发:",-1)),t("span",{class:S(["font-medium",s.currentConcurrency>0?"text-orange-600":"text-gray-600"])},[f(p(s.currentConcurrency||0)+" ",1),s.concurrencyLimit>0?(r(),d("span",bl,"/ "+p(s.concurrencyLimit),1)):A("",!0)],2)]),s.rateLimitWindow>0?(r(),d("div",vl,[e[34]||(e[34]=t("span",{class:"text-gray-600"},"时间窗口:",-1)),t("span",wl,p(s.rateLimitWindow)+" 分钟",1)])):A("",!0),s.rateLimitRequests>0?(r(),d("div",$l,[e[35]||(e[35]=t("span",{class:"text-gray-600"},"请求限制:",-1)),t("span",Cl,p(s.rateLimitRequests)+" 次/窗口",1)])):A("",!0),t("div",Al,[t("span",null,"输入: "+p(R(s.usage&&s.usage.total&&s.usage.total.inputTokens||0)),1),t("span",null,"输出: "+p(R(s.usage&&s.usage.total&&s.usage.total.outputTokens||0)),1)]),(s.usage&&s.usage.total&&s.usage.total.cacheCreateTokens||0)>0||(s.usage&&s.usage.total&&s.usage.total.cacheReadTokens||0)>0?(r(),d("div",kl,[t("span",null,"缓存创建: "+p(R(s.usage&&s.usage.total&&s.usage.total.cacheCreateTokens||0)),1),t("span",null,"缓存读取: "+p(R(s.usage&&s.usage.total&&s.usage.total.cacheReadTokens||0)),1)])):A("",!0),t("div",Kl,[t("span",null,"RPM: "+p(s.usage&&s.usage.averages&&s.usage.averages.rpm||0),1),t("span",null,"TPM: "+p(s.usage&&s.usage.averages&&s.usage.averages.tpm||0),1)]),t("div",Ll,[t("div",Dl,[t("span",null,"今日: "+p(R(s.usage&&s.usage.daily&&s.usage.daily.requests||0))+"次",1),t("span",null,p(R(s.usage&&s.usage.daily&&s.usage.daily.tokens||0))+"T",1)])]),t("div",Il,[s&&s.id?(r(),d("button",{key:0,onClick:c=>yt(s.id),class:"text-xs text-indigo-600 hover:text-indigo-800 font-medium"},[t("i",{class:S(["fas",n.value[s.id]?"fa-chevron-up":"fa-chevron-down","mr-1"])},null,2),e[36]||(e[36]=f(" 模型使用分布 ",-1))],8,Ml)):A("",!0)])])]),t("td",Rl,p(new Date(s.createdAt).toLocaleDateString()),1),t("td",Sl,[s.expiresAt?(r(),d("div",hl,[et(s.expiresAt)?(r(),d("div",Tl,e[37]||(e[37]=[t("i",{class:"fas fa-exclamation-circle mr-1"},null,-1),f(" 已过期 ",-1)]))):at(s.expiresAt)?(r(),d("div",El,[e[38]||(e[38]=t("i",{class:"fas fa-clock mr-1"},null,-1)),f(" "+p(rt(s.expiresAt)),1)])):(r(),d("div",Pl,p(rt(s.expiresAt)),1))])):(r(),d("div",jl,e[39]||(e[39]=[t("i",{class:"fas fa-infinity mr-1"},null,-1),f(" 永不过期 ",-1)])))]),t("td",Vl,[t("div",_l,[t("button",{onClick:c=>Dt(s),class:"text-purple-600 hover:text-purple-900 font-medium hover:bg-purple-50 px-3 py-1 rounded-lg transition-colors",title:"复制统计页面链接"},e[40]||(e[40]=[t("i",{class:"fas fa-chart-bar mr-1"},null,-1),f("统计 ",-1)]),8,Ul),t("button",{onClick:c=>$t(s),class:"text-blue-600 hover:text-blue-900 font-medium hover:bg-blue-50 px-3 py-1 rounded-lg transition-colors"},e[41]||(e[41]=[t("i",{class:"fas fa-edit mr-1"},null,-1),f("编辑 ",-1)]),8,ql),s.expiresAt&&(et(s.expiresAt)||at(s.expiresAt))?(r(),d("button",{key:0,onClick:c=>Ct(s),class:"text-green-600 hover:text-green-900 font-medium hover:bg-green-50 px-3 py-1 rounded-lg transition-colors"},e[42]||(e[42]=[t("i",{class:"fas fa-clock mr-1"},null,-1),f("续期 ",-1)]),8,Ol)):A("",!0),t("button",{onClick:c=>Lt(s.id),class:"text-red-600 hover:text-red-900 font-medium hover:bg-red-50 px-3 py-1 rounded-lg transition-colors"},e[43]||(e[43]=[t("i",{class:"fas fa-trash mr-1"},null,-1),f("删除 ",-1)]),8,Fl)])])]),s&&s.id&&n.value[s.id]?(r(),d("tr",Wl,[t("td",zl,[$.value[s.id]?A("",!0):(r(),d("div",Yl,e[44]||(e[44]=[t("div",{class:"loading-spinner mx-auto"},null,-1),t("p",{class:"text-sm text-gray-500 mt-2"},"加载模型统计...",-1)]))),t("div",Nl,[t("div",Hl,[e[45]||(e[45]=t("h5",{class:"text-sm font-semibold text-gray-700 flex items-center"},[t("i",{class:"fas fa-chart-pie text-indigo-500 mr-2"}),f(" 模型使用分布 ")],-1)),t("div",Bl,[$.value[s.id]&&$.value[s.id].length>0?(r(),d("span",Gl,p($.value[s.id].length)+" 个模型 ",1)):A("",!0),t("div",Xl,[t("div",Ql,[(r(!0),d(h,null,E(U(s.id).presetOptions,c=>(r(),d("button",{key:c.value,onClick:T=>mt(c.value,s.id),class:S(["px-2 py-1 rounded text-xs font-medium transition-colors",U(s.id).preset===c.value&&U(s.id).type==="preset"?"bg-white text-blue-600 shadow-sm":"text-gray-600 hover:text-gray-900"])},p(c.label),11,Jl))),128))]),Rt(g,{"model-value":U(s.id).customRange,"onUpdate:modelValue":c=>gt(s.id,c),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":bt,"default-time":P.value,size:"small",style:{width:"280px"},class:"api-key-date-picker",clearable:!0,"unlink-panels":!1},null,8,["model-value","onUpdate:modelValue","default-time"])])])]),$.value[s.id]&&$.value[s.id].length===0?(r(),d("div",Zl,[t("div",to,[e[47]||(e[47]=t("i",{class:"fas fa-chart-line text-gray-400 text-lg"},null,-1)),e[48]||(e[48]=t("p",{class:"text-sm text-gray-500"},"暂无模型使用数据",-1)),t("button",{onClick:c=>vt(s.id),class:"text-blue-500 hover:text-blue-700 text-sm ml-2 flex items-center gap-1 transition-colors",title:"重置筛选条件并刷新"},e[46]||(e[46]=[t("i",{class:"fas fa-sync-alt text-xs"},null,-1),t("span",{class:"text-xs"},"刷新",-1)]),8,eo)]),e[49]||(e[49]=t("p",{class:"text-xs text-gray-400"},"尝试调整时间范围或点击刷新重新加载数据",-1))])):$.value[s.id]&&$.value[s.id].length>0?(r(),d("div",so,[(r(!0),d(h,null,E($.value[s.id],c=>(r(),d("div",{key:c.model,class:"bg-gradient-to-br from-white to-gray-50 rounded-xl p-4 border border-gray-200 hover:border-indigo-300 hover:shadow-lg transition-all duration-200"},[t("div",lo,[t("div",oo,[t("span",io,p(c.model),1),t("span",no,p(c.requests)+" 次请求",1)])]),t("div",ao,[t("div",ro,[e[50]||(e[50]=t("span",{class:"text-gray-600 flex items-center"},[t("i",{class:"fas fa-coins text-yellow-500 mr-1 text-xs"}),f(" 总Token: ")],-1)),t("span",uo,p(R(c.allTokens)),1)]),t("div",mo,[e[51]||(e[51]=t("span",{class:"text-gray-600 flex items-center"},[t("i",{class:"fas fa-dollar-sign text-green-500 mr-1 text-xs"}),f(" 费用: ")],-1)),t("span",po,p(ft(c)),1)]),t("div",co,[t("div",xo,[e[52]||(e[52]=t("span",{class:"flex items-center"},[t("i",{class:"fas fa-arrow-down text-green-500 mr-1"}),f(" 输入: ")],-1)),t("span",yo,p(R(c.inputTokens)),1)]),t("div",fo,[e[53]||(e[53]=t("span",{class:"flex items-center"},[t("i",{class:"fas fa-arrow-up text-blue-500 mr-1"}),f(" 输出: ")],-1)),t("span",go,p(R(c.outputTokens)),1)]),c.cacheCreateTokens>0?(r(),d("div",bo,[e[54]||(e[54]=t("span",{class:"flex items-center"},[t("i",{class:"fas fa-save mr-1"}),f(" 缓存创建: ")],-1)),t("span",vo,p(R(c.cacheCreateTokens)),1)])):A("",!0),c.cacheReadTokens>0?(r(),d("div",wo,[e[55]||(e[55]=t("span",{class:"flex items-center"},[t("i",{class:"fas fa-download mr-1"}),f(" 缓存读取: ")],-1)),t("span",$o,p(R(c.cacheReadTokens)),1)])):A("",!0)])]),t("div",Co,[t("div",{class:"bg-gradient-to-r from-indigo-500 to-purple-600 h-2 rounded-full transition-all duration-500",style:St({width:dt(c.allTokens,$.value[s.id])+"%"})},null,4)]),t("div",Ao,[t("span",ko,p(dt(c.allTokens,$.value[s.id]))+"% ",1)])]))),128))])):A("",!0),$.value[s.id]&&$.value[s.id].length>0?(r(),d("div",Ko,[t("div",Lo,[e[58]||(e[58]=t("span",{class:"font-semibold text-gray-700 flex items-center"},[t("i",{class:"fas fa-calculator text-indigo-500 mr-2"}),f(" 总计统计 ")],-1)),t("div",Do,[t("span",Io,[e[56]||(e[56]=f(" 总请求: ",-1)),t("span",Mo,p($.value[s.id].reduce((c,T)=>c+T.requests,0)),1)]),t("span",Ro,[e[57]||(e[57]=f(" 总Token: ",-1)),t("span",So,p(R($.value[s.id].reduce((c,T)=>c+T.allTokens,0))),1)])])])])):A("",!0)])])])):A("",!0)],64))),128))])])]))]),l.value?(r(),q(ye,{key:0,accounts:y.value,onClose:e[7]||(e[7]=s=>l.value=!1),onSuccess:At},null,8,["accounts"])):A("",!0),m.value?(r(),q(Qe,{key:1,apiKey:u.value,accounts:y.value,onClose:e[8]||(e[8]=s=>m.value=!1),onSuccess:kt},null,8,["apiKey","accounts"])):A("",!0),b.value?(r(),q(xs,{key:2,apiKey:j.value,onClose:e[9]||(e[9]=s=>b.value=!1),onSuccess:Kt},null,8,["apiKey"])):A("",!0),o.value?(r(),q(hs,{key:3,apiKeyData:N.value,onClose:e[10]||(e[10]=s=>o.value=!1)},null,8,["apiKeyData"])):A("",!0)])}}},_o=G(ho,[["__scopeId","data-v-b60a91aa"]]);export{_o as default};