mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
20 lines
103 KiB
JavaScript
20 lines
103 KiB
JavaScript
import{E as Xe}from"./element-plus-B8Fs_0jW.js";import{aR as je,r as K,c as ee,_ as be,q as he,I as Z,y as n,z as e,Y as ie,x as i,L as y,C as P,K as D,an as ne,O as h,aq as z,P as u,Q as R,ac as G,aa as ye,aX as le,al as de,a5 as ue,o as $e,R as Se,B as Je}from"./vue-vendor-CKToUHZx.js";import{s as S}from"./toast-BvwA7Mwb.js";import{a as U,_ as ae,u as Re}from"./index-D3bIJLrk.js";import"./vendor-BDiMbLwQ.js";const Ae=je("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 I=await U.get("/admin/supported-clients");return I.success?this.supportedClients=I.data||[]:(this.error=I.message||"加载支持的客户端失败",console.error("Failed to load supported clients:",this.error)),this.supportedClients}catch(I){return this.error=I.message||"加载支持的客户端失败",console.error("Error loading supported clients:",I),[]}finally{this.loading=!1}}}}),Ee=je("apiKeys",()=>{const I=K([]),V=K(!1),f=K(null),M=K("all"),j=K(""),C=K("asc"),$=async()=>{V.value=!0,f.value=null;try{const A=await U.get("/admin/api-keys");if(A.success)I.value=A.data||[];else throw new Error(A.message||"获取API Keys失败")}catch(A){throw f.value=A.message,A}finally{V.value=!1}};return{apiKeys:I,loading:V,error:f,statsTimeRange:M,sortBy:j,sortOrder:C,fetchApiKeys:$,createApiKey:async A=>{V.value=!0,f.value=null;try{const x=await U.post("/admin/api-keys",A);if(x.success)return await $(),x.data;throw new Error(x.message||"创建API Key失败")}catch(x){throw f.value=x.message,x}finally{V.value=!1}},updateApiKey:async(A,x)=>{V.value=!0,f.value=null;try{const p=await U.put(`/admin/api-keys/${A}`,x);if(p.success)return await $(),p;throw new Error(p.message||"更新API Key失败")}catch(p){throw f.value=p.message,p}finally{V.value=!1}},toggleApiKey:async A=>{V.value=!0,f.value=null;try{const x=await U.put(`/admin/api-keys/${A}/toggle`);if(x.success)return await $(),x;throw new Error(x.message||"切换状态失败")}catch(x){throw f.value=x.message,x}finally{V.value=!1}},renewApiKey:async(A,x)=>{V.value=!0,f.value=null;try{const p=await U.put(`/admin/api-keys/${A}/renew`,x);if(p.success)return await $(),p;throw new Error(p.message||"续期失败")}catch(p){throw f.value=p.message,p}finally{V.value=!1}},deleteApiKey:async A=>{V.value=!0,f.value=null;try{const x=await U.delete(`/admin/api-keys/${A}`);if(x.success)return await $(),x;throw new Error(x.message||"删除失败")}catch(x){throw f.value=x.message,x}finally{V.value=!1}},fetchApiKeyStats:async(A,x="all")=>{try{const p=await U.get(`/admin/api-keys/${A}/stats`,{params:{timeRange:x}});if(p.success)return p.stats;throw new Error(p.message||"获取统计失败")}catch(p){return console.error("获取API Key统计失败:",p),null}},fetchTags:async()=>{try{const A=await U.get("/admin/api-keys/tags");if(A.success)return A.data||[];throw new Error(A.message||"获取标签失败")}catch(A){return console.error("获取标签失败:",A),[]}},sortApiKeys:A=>{j.value===A?C.value=C.value==="asc"?"desc":"asc":(j.value=A,C.value="asc")},reset:()=>{I.value=[],V.value=!1,f.value=null,M.value="all",j.value="",C.value="asc"}}}),Ze={class:"fixed inset-0 modal z-50 flex items-center justify-center p-3 sm:p-4"},et={class:"modal-content w-full max-w-4xl p-4 sm:p-6 mx-auto max-h-[90vh] flex flex-col"},tt={class:"flex items-center justify-between mb-4"},st={class:"bg-gradient-to-r from-blue-50 to-indigo-50 rounded-lg p-3 sm:p-4 border border-blue-200"},lt={class:"flex gap-3 sm:gap-4 items-center"},ot={class:"flex items-center cursor-pointer"},nt={class:"flex items-center cursor-pointer"},it={key:0,class:"mt-3"},at={class:"flex items-center gap-4"},rt={class:"flex-1"},dt={class:"flex items-center gap-2"},ut={class:"text-xs text-amber-600 mt-2 flex items-start"},ct=["placeholder"],mt={key:0,class:"text-red-500 text-xs mt-1"},pt={class:"space-y-4"},xt={key:0},gt={class:"flex flex-wrap gap-2"},ft=["onClick"],yt={key:1},bt={class:"flex flex-wrap gap-2"},vt=["onClick"],wt={class:"flex gap-2"},$t=["onKeypress"],ht={class:"bg-blue-50 border border-blue-200 rounded-lg p-3"},At={class:"space-y-2"},Ct={class:"grid grid-cols-1 lg:grid-cols-3 gap-2"},Kt={class:"space-y-2"},kt={class:"flex gap-2"},_t={key:0,class:"mt-3"},Dt=["min"],It={key:1,class:"text-xs text-gray-500 mt-2"},Lt={class:"flex gap-4"},Tt={class:"flex items-center cursor-pointer"},Mt={class:"flex items-center cursor-pointer"},St={class:"flex items-center cursor-pointer"},jt={class:"flex items-center justify-between mb-2"},Rt=["disabled"],Et={class:"grid grid-cols-1 gap-3"},Pt=["disabled"],Ut={key:0,label:"调度分组"},Vt=["value"],Gt={key:1,label:"Claude OAuth 专属账号"},Ot=["value"],qt={key:2,label:"Claude Console 专属账号"},Ft=["value"],Wt=["disabled"],zt={key:0,label:"调度分组"},Nt=["value"],Yt={key:1,label:"Gemini 专属账号"},Bt=["value"],Ht={class:"flex items-center mb-2"},Qt={key:0,class:"space-y-2 bg-red-50 border border-red-200 rounded-lg p-3"},Xt={class:"flex flex-wrap gap-1 mb-2 min-h-[24px]"},Jt=["onClick"],Zt={key:0,class:"text-gray-400 text-xs"},es={class:"flex gap-2"},ts=["onKeydown"],ss={class:"flex items-center mb-2"},ls={key:0,class:"bg-green-50 border border-green-200 rounded-lg p-3"},os={class:"space-y-1"},ns=["id","value"],is=["for"],as={class:"text-sm font-medium text-gray-700"},rs={class:"text-xs text-gray-500 block"},ds={class:"flex gap-3 pt-2"},us=["disabled"],cs={key:0,class:"loading-spinner mr-2"},ms={key:1,class:"fas fa-plus mr-2"},ps={__name:"CreateApiKeyModal",props:{accounts:{type:Object,default:()=>({claude:[],gemini:[]})}},emits:["close","success","batch-success"],setup(I,{emit:V}){const f=I,M=V,j=Ae(),C=Ee(),$=K(!1),O=K(!1),b=K({claude:[],gemini:[],claudeGroups:[],geminiGroups:[]}),q=K({name:""}),L=K(""),w=K([]),k=ee(()=>w.value.filter(_=>!l.tags.includes(_))),d=K([]),l=be({createType:"single",batchCount:10,name:"",description:"",tokenLimit:"",rateLimitWindow:"",rateLimitRequests:"",concurrencyLimit:"",dailyCostLimit:"",expireDuration:"",customExpireDate:"",expiresAt:null,permissions:"all",claudeAccountId:"",geminiAccountId:"",enableModelRestriction:!1,restrictedModels:[],modelInput:"",enableClientRestriction:!1,allowedClients:[],tags:[]});he(async()=>{d.value=await j.loadSupportedClients(),w.value=await C.fetchTags(),f.accounts&&(b.value={claude:f.accounts.claude||[],gemini:f.accounts.gemini||[],claudeGroups:f.accounts.claudeGroups||[],geminiGroups:f.accounts.geminiGroups||[]})});const N=async()=>{var _,o;O.value=!0;try{const[r,F,Q,se]=await Promise.all([U.get("/admin/claude-accounts"),U.get("/admin/claude-console-accounts"),U.get("/admin/gemini-accounts"),U.get("/admin/account-groups")]),re=[];if(r.success&&((_=r.data)==null||_.forEach(X=>{re.push({...X,platform:"claude-oauth",isDedicated:X.accountType==="dedicated"})})),F.success&&((o=F.data)==null||o.forEach(X=>{re.push({...X,platform:"claude-console",isDedicated:X.accountType==="dedicated"})})),b.value.claude=re,Q.success&&(b.value.gemini=(Q.data||[]).map(X=>({...X,isDedicated:X.accountType==="dedicated"}))),se.success){const X=se.data||[];b.value.claudeGroups=X.filter(J=>J.platform==="claude"),b.value.geminiGroups=X.filter(J=>J.platform==="gemini")}S("账号列表已刷新","success")}catch{S("刷新账号列表失败","error")}finally{O.value=!1}},A=ee(()=>{const _=new Date;return _.setMinutes(_.getMinutes()+1),_.toISOString().slice(0,16)}),x=()=>{if(!l.expireDuration){l.expiresAt=null;return}if(l.expireDuration==="custom")return;const _=new Date,r=l.expireDuration.match(/(\d+)([dhmy])/);if(r){const[,F,Q]=r,se=parseInt(F);switch(Q){case"d":_.setDate(_.getDate()+se);break;case"h":_.setHours(_.getHours()+se);break;case"m":_.setMonth(_.getMonth()+se);break;case"y":_.setFullYear(_.getFullYear()+se);break}l.expiresAt=_.toISOString()}},p=()=>{l.customExpireDate&&(l.expiresAt=new Date(l.customExpireDate).toISOString())},Y=_=>new Date(_).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}),H=()=>{l.modelInput&&!l.restrictedModels.includes(l.modelInput)&&(l.restrictedModels.push(l.modelInput),l.modelInput="")},T=_=>{l.restrictedModels.splice(_,1)},a=()=>{if(L.value&&L.value.trim()){const _=L.value.trim();l.tags.includes(_)||l.tags.push(_),L.value=""}},m=_=>{l.tags.includes(_)||l.tags.push(_)},B=_=>{l.tags.splice(_,1)},te=async()=>{if(q.value.name="",!l.name||!l.name.trim()){q.value.name="请输入API Key名称";return}if(l.createType==="batch"&&(!l.batchCount||l.batchCount<2||l.batchCount>500)){S("批量创建数量必须在 2-500 之间","error");return}$.value=!0;try{const _={description:l.description||void 0,tokenLimit:l.tokenLimit!==""&&l.tokenLimit!==null?parseInt(l.tokenLimit):null,rateLimitWindow:l.rateLimitWindow!==""&&l.rateLimitWindow!==null?parseInt(l.rateLimitWindow):null,rateLimitRequests:l.rateLimitRequests!==""&&l.rateLimitRequests!==null?parseInt(l.rateLimitRequests):null,concurrencyLimit:l.concurrencyLimit!==""&&l.concurrencyLimit!==null?parseInt(l.concurrencyLimit):0,dailyCostLimit:l.dailyCostLimit!==""&&l.dailyCostLimit!==null?parseFloat(l.dailyCostLimit):0,expiresAt:l.expiresAt||void 0,permissions:l.permissions,tags:l.tags.length>0?l.tags:void 0,enableModelRestriction:l.enableModelRestriction,restrictedModels:l.restrictedModels,enableClientRestriction:l.enableClientRestriction,allowedClients:l.allowedClients};if(l.claudeAccountId&&(l.claudeAccountId.startsWith("console:")?_.claudeConsoleAccountId=l.claudeAccountId.substring(8):_.claudeAccountId=l.claudeAccountId),l.geminiAccountId&&(_.geminiAccountId=l.geminiAccountId),l.createType==="single"){const o={..._,name:l.name},r=await U.post("/admin/api-keys",o);r.success?(S("API Key 创建成功","success"),M("success",r.data),M("close")):S(r.message||"创建失败","error")}else{const o={..._,createType:"batch",baseName:l.name,count:l.batchCount},r=await U.post("/admin/api-keys/batch",o);r.success?(S(`成功创建 ${r.data.length} 个 API Key`,"success"),M("batch-success",r.data),M("close")):S(r.message||"批量创建失败","error")}}catch{S("创建失败","error")}finally{$.value=!1}};return(_,o)=>(n(),Z(ue,{to:"body"},[e("div",Ze,[e("div",et,[e("div",tt,[o[30]||(o[30]=e("div",{class:"flex items-center gap-2 sm:gap-3"},[e("div",{class:"w-8 h-8 sm:w-10 sm:h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg sm:rounded-xl flex items-center justify-center"},[e("i",{class:"fas fa-key text-white text-sm sm:text-base"})]),e("h3",{class:"text-lg sm:text-xl font-bold text-gray-900"}," 创建新的 API Key ")],-1)),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors p-1",onClick:o[0]||(o[0]=r=>_.$emit("close"))},o[29]||(o[29]=[e("i",{class:"fas fa-times text-lg sm:text-xl"},null,-1)]))]),e("form",{class:"space-y-4 modal-scroll-content custom-scrollbar flex-1",onSubmit:ie(te,["prevent"])},[e("div",st,[e("div",{class:P(["flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3",l.createType==="batch"?"mb-3":""])},[o[33]||(o[33]=e("label",{class:"text-xs sm:text-sm font-semibold text-gray-700 flex items-center h-full"},"创建类型",-1)),e("div",lt,[e("label",ot,[D(e("input",{"onUpdate:modelValue":o[1]||(o[1]=r=>l.createType=r),type:"radio",value:"single",class:"mr-1.5 sm:mr-2 text-blue-600"},null,512),[[ne,l.createType]]),o[31]||(o[31]=e("span",{class:"text-xs sm:text-sm text-gray-700 flex items-center"},[e("i",{class:"fas fa-key mr-1 text-xs"}),h(" 单个创建 ")],-1))]),e("label",nt,[D(e("input",{"onUpdate:modelValue":o[2]||(o[2]=r=>l.createType=r),type:"radio",value:"batch",class:"mr-1.5 sm:mr-2 text-blue-600"},null,512),[[ne,l.createType]]),o[32]||(o[32]=e("span",{class:"text-xs sm:text-sm text-gray-700 flex items-center"},[e("i",{class:"fas fa-layer-group mr-1 text-xs"}),h(" 批量创建 ")],-1))])])],2),l.createType==="batch"?(n(),i("div",it,[e("div",at,[e("div",rt,[o[35]||(o[35]=e("label",{class:"block text-xs font-medium text-gray-600 mb-1"},"创建数量",-1)),e("div",dt,[D(e("input",{"onUpdate:modelValue":o[3]||(o[3]=r=>l.batchCount=r),type:"number",min:"2",max:"500",required:"",class:"form-input w-full text-sm",placeholder:"输入数量 (2-500)"},null,512),[[z,l.batchCount,void 0,{number:!0}]]),o[34]||(o[34]=e("div",{class:"text-xs text-gray-500 whitespace-nowrap"}," 最大支持 500 个 ",-1))])])]),e("p",ut,[o[36]||(o[36]=e("i",{class:"fas fa-info-circle mr-1 mt-0.5 flex-shrink-0"},null,-1)),e("span",null,"批量创建时,每个 Key 的名称会自动添加序号后缀,例如:"+u(l.name||"MyKey")+"_1, "+u(l.name||"MyKey")+"_2 ...",1)])])):y("",!0)]),e("div",null,[o[37]||(o[37]=e("label",{class:"block text-xs sm:text-sm font-semibold text-gray-700 mb-1.5 sm:mb-2"},[h("名称 "),e("span",{class:"text-red-500"},"*")],-1)),D(e("input",{"onUpdate:modelValue":o[4]||(o[4]=r=>l.name=r),type:"text",required:"",class:P(["form-input w-full text-sm",{"border-red-500":q.value.name}]),placeholder:l.createType==="batch"?"输入基础名称(将自动添加序号)":"为您的 API Key 取一个名称",onInput:o[5]||(o[5]=r=>q.value.name="")},null,42,ct),[[z,l.name]]),q.value.name?(n(),i("p",mt,u(q.value.name),1)):y("",!0)]),e("div",null,[o[45]||(o[45]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"标签",-1)),e("div",pt,[l.tags.length>0?(n(),i("div",xt,[o[39]||(o[39]=e("div",{class:"text-xs font-medium text-gray-600 mb-2"}," 已选择的标签: ",-1)),e("div",gt,[(n(!0),i(R,null,G(l.tags,(r,F)=>(n(),i("span",{key:"selected-"+F,class:"inline-flex items-center gap-1 px-3 py-1 bg-blue-100 text-blue-800 text-sm rounded-full"},[h(u(r)+" ",1),e("button",{type:"button",class:"ml-1 hover:text-blue-900",onClick:Q=>B(F)},o[38]||(o[38]=[e("i",{class:"fas fa-times text-xs"},null,-1)]),8,ft)]))),128))])])):y("",!0),k.value.length>0?(n(),i("div",yt,[o[41]||(o[41]=e("div",{class:"text-xs font-medium text-gray-600 mb-2"}," 点击选择已有标签: ",-1)),e("div",bt,[(n(!0),i(R,null,G(k.value,r=>(n(),i("button",{key:"available-"+r,type:"button",class:"inline-flex items-center gap-1 px-3 py-1 bg-gray-100 text-gray-700 text-sm rounded-full hover:bg-blue-100 hover:text-blue-700 transition-colors",onClick:F=>m(r)},[o[40]||(o[40]=e("i",{class:"fas fa-tag text-gray-500 text-xs"},null,-1)),h(" "+u(r),1)],8,vt))),128))])])):y("",!0),e("div",null,[o[43]||(o[43]=e("div",{class:"text-xs font-medium text-gray-600 mb-2"}," 创建新标签: ",-1)),e("div",wt,[D(e("input",{"onUpdate:modelValue":o[6]||(o[6]=r=>L.value=r),type:"text",class:"form-input flex-1",placeholder:"输入新标签名称",onKeypress:ye(ie(a,["prevent"]),["enter"])},null,40,$t),[[z,L.value]]),e("button",{type:"button",class:"px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors",onClick:a},o[42]||(o[42]=[e("i",{class:"fas fa-plus"},null,-1)]))])]),o[44]||(o[44]=e("p",{class:"text-xs text-gray-500"}," 用于标记不同团队或用途,方便筛选管理 ",-1))])]),e("div",ht,[o[53]||(o[53]=e("div",{class:"flex items-center gap-2 mb-2"},[e("div",{class:"w-6 h-6 bg-blue-500 rounded flex items-center justify-center flex-shrink-0"},[e("i",{class:"fas fa-tachometer-alt text-white text-xs"})]),e("h4",{class:"font-semibold text-gray-800 text-sm"}," 速率限制设置 (可选) ")],-1)),e("div",At,[e("div",Ct,[e("div",null,[o[46]||(o[46]=e("label",{class:"block text-xs font-medium text-gray-700 mb-1"},"时间窗口 (分钟)",-1)),D(e("input",{"onUpdate:modelValue":o[7]||(o[7]=r=>l.rateLimitWindow=r),type:"number",min:"1",placeholder:"无限制",class:"form-input w-full text-sm"},null,512),[[z,l.rateLimitWindow]]),o[47]||(o[47]=e("p",{class:"text-xs text-gray-500 mt-0.5 ml-2"}," 时间段单位 ",-1))]),e("div",null,[o[48]||(o[48]=e("label",{class:"block text-xs font-medium text-gray-700 mb-1"},"请求次数限制",-1)),D(e("input",{"onUpdate:modelValue":o[8]||(o[8]=r=>l.rateLimitRequests=r),type:"number",min:"1",placeholder:"无限制",class:"form-input w-full text-sm"},null,512),[[z,l.rateLimitRequests]]),o[49]||(o[49]=e("p",{class:"text-xs text-gray-500 mt-0.5 ml-2"}," 窗口内最大请求 ",-1))]),e("div",null,[o[50]||(o[50]=e("label",{class:"block text-xs font-medium text-gray-700 mb-1"},"Token 限制",-1)),D(e("input",{"onUpdate:modelValue":o[9]||(o[9]=r=>l.tokenLimit=r),type:"number",placeholder:"无限制",class:"form-input w-full text-sm"},null,512),[[z,l.tokenLimit]]),o[51]||(o[51]=e("p",{class:"text-xs text-gray-500 mt-0.5 ml-2"}," 窗口内最大Token ",-1))])]),o[52]||(o[52]=e("div",{class:"bg-blue-100 rounded-lg p-2"},[e("h5",{class:"text-xs font-semibold text-blue-800 mb-1"}," 💡 使用示例 "),e("div",{class:"text-xs text-blue-700 space-y-0.5"},[e("div",null,[e("strong",null,"示例1:"),h(" 时间窗口=60,请求次数=1000 → 每60分钟最多1000次请求")]),e("div",null,[e("strong",null,"示例2:"),h(" 时间窗口=1,Token=10000 → 每分钟最多10,000个Token")]),e("div",null,[e("strong",null,"示例3:"),h(" 窗口=30,请求=50,Token=100000 → 每30分钟50次请求且不超10万Token")])])],-1))])]),e("div",null,[o[55]||(o[55]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"每日费用限制 (美元)",-1)),e("div",Kt,[e("div",kt,[e("button",{type:"button",class:"px-2 py-1 bg-gray-100 hover:bg-gray-200 rounded text-xs font-medium",onClick:o[10]||(o[10]=r=>l.dailyCostLimit="50")}," $50 "),e("button",{type:"button",class:"px-2 py-1 bg-gray-100 hover:bg-gray-200 rounded text-xs font-medium",onClick:o[11]||(o[11]=r=>l.dailyCostLimit="100")}," $100 "),e("button",{type:"button",class:"px-2 py-1 bg-gray-100 hover:bg-gray-200 rounded text-xs font-medium",onClick:o[12]||(o[12]=r=>l.dailyCostLimit="200")}," $200 "),e("button",{type:"button",class:"px-2 py-1 bg-gray-100 hover:bg-gray-200 rounded text-xs font-medium",onClick:o[13]||(o[13]=r=>l.dailyCostLimit="")}," 自定义 ")]),D(e("input",{"onUpdate:modelValue":o[14]||(o[14]=r=>l.dailyCostLimit=r),type:"number",min:"0",step:"0.01",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[z,l.dailyCostLimit]]),o[54]||(o[54]=e("p",{class:"text-xs text-gray-500"}," 设置此 API Key 每日的费用限制,超过限制将拒绝请求,0 或留空表示无限制 ",-1))])]),e("div",null,[o[56]||(o[56]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"并发限制 (可选)",-1)),D(e("input",{"onUpdate:modelValue":o[15]||(o[15]=r=>l.concurrencyLimit=r),type:"number",min:"0",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[z,l.concurrencyLimit]]),o[57]||(o[57]=e("p",{class:"text-xs text-gray-500 mt-2"}," 设置此 API Key 可同时处理的最大请求数,0 或留空表示无限制 ",-1))]),e("div",null,[o[58]||(o[58]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"备注 (可选)",-1)),D(e("textarea",{"onUpdate:modelValue":o[16]||(o[16]=r=>l.description=r),rows:"2",class:"form-input w-full resize-none text-sm",placeholder:"描述此 API Key 的用途..."},null,512),[[z,l.description]])]),e("div",null,[o[60]||(o[60]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"有效期限",-1)),D(e("select",{"onUpdate:modelValue":o[17]||(o[17]=r=>l.expireDuration=r),class:"form-input w-full",onChange:x},o[59]||(o[59]=[e("option",{value:""}," 永不过期 ",-1),e("option",{value:"1d"}," 1 天 ",-1),e("option",{value:"7d"}," 7 天 ",-1),e("option",{value:"30d"}," 30 天 ",-1),e("option",{value:"90d"}," 90 天 ",-1),e("option",{value:"180d"}," 180 天 ",-1),e("option",{value:"365d"}," 365 天 ",-1),e("option",{value:"custom"}," 自定义日期 ",-1)]),544),[[le,l.expireDuration]]),l.expireDuration==="custom"?(n(),i("div",_t,[D(e("input",{"onUpdate:modelValue":o[18]||(o[18]=r=>l.customExpireDate=r),type:"datetime-local",class:"form-input w-full",min:A.value,onChange:p},null,40,Dt),[[z,l.customExpireDate]])])):y("",!0),l.expiresAt?(n(),i("p",It," 将于 "+u(Y(l.expiresAt))+" 过期 ",1)):y("",!0)]),e("div",null,[o[64]||(o[64]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"服务权限",-1)),e("div",Lt,[e("label",Tt,[D(e("input",{"onUpdate:modelValue":o[19]||(o[19]=r=>l.permissions=r),type:"radio",value:"all",class:"mr-2"},null,512),[[ne,l.permissions]]),o[61]||(o[61]=e("span",{class:"text-sm text-gray-700"},"全部服务",-1))]),e("label",Mt,[D(e("input",{"onUpdate:modelValue":o[20]||(o[20]=r=>l.permissions=r),type:"radio",value:"claude",class:"mr-2"},null,512),[[ne,l.permissions]]),o[62]||(o[62]=e("span",{class:"text-sm text-gray-700"},"仅 Claude",-1))]),e("label",St,[D(e("input",{"onUpdate:modelValue":o[21]||(o[21]=r=>l.permissions=r),type:"radio",value:"gemini",class:"mr-2"},null,512),[[ne,l.permissions]]),o[63]||(o[63]=e("span",{class:"text-sm text-gray-700"},"仅 Gemini",-1))])]),o[65]||(o[65]=e("p",{class:"text-xs text-gray-500 mt-2"}," 控制此 API Key 可以访问哪些服务 ",-1))]),e("div",null,[e("div",jt,[o[66]||(o[66]=e("label",{class:"text-sm font-semibold text-gray-700"},"专属账号绑定 (可选)",-1)),e("button",{type:"button",class:"text-blue-600 hover:text-blue-800 text-sm flex items-center gap-1 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",title:"刷新账号列表",disabled:O.value,onClick:N},[e("i",{class:P(["fas",O.value?"fa-spinner fa-spin":"fa-sync-alt","text-xs"])},null,2),e("span",null,u(O.value?"刷新中...":"刷新账号"),1)],8,Rt)]),e("div",Et,[e("div",null,[o[68]||(o[68]=e("label",{class:"block text-sm font-medium text-gray-600 mb-1"},"Claude 专属账号",-1)),D(e("select",{"onUpdate:modelValue":o[22]||(o[22]=r=>l.claudeAccountId=r),class:"form-input w-full",disabled:l.permissions==="gemini"},[o[67]||(o[67]=e("option",{value:""}," 使用共享账号池 ",-1)),b.value.claudeGroups&&b.value.claudeGroups.length>0?(n(),i("optgroup",Ut,[(n(!0),i(R,null,G(b.value.claudeGroups,r=>(n(),i("option",{key:`group:${r.id}`,value:`group:${r.id}`},u(r.name)+" ("+u(r.memberCount||0)+" 个成员) ",9,Vt))),128))])):y("",!0),b.value.claude.filter(r=>r.accountType==="dedicated"&&r.platform==="claude-oauth").length>0?(n(),i("optgroup",Gt,[(n(!0),i(R,null,G(b.value.claude.filter(r=>r.accountType==="dedicated"&&r.platform==="claude-oauth"),r=>(n(),i("option",{key:r.id,value:r.id},u(r.name)+" ("+u(r.status==="active"?"正常":"异常")+") ",9,Ot))),128))])):y("",!0),b.value.claude.filter(r=>r.accountType==="dedicated"&&r.platform==="claude-console").length>0?(n(),i("optgroup",qt,[(n(!0),i(R,null,G(b.value.claude.filter(r=>r.accountType==="dedicated"&&r.platform==="claude-console"),r=>(n(),i("option",{key:r.id,value:`console:${r.id}`},u(r.name)+" ("+u(r.status==="active"?"正常":"异常")+") ",9,Ft))),128))])):y("",!0)],8,Pt),[[le,l.claudeAccountId]])]),e("div",null,[o[70]||(o[70]=e("label",{class:"block text-sm font-medium text-gray-600 mb-1"},"Gemini 专属账号",-1)),D(e("select",{"onUpdate:modelValue":o[23]||(o[23]=r=>l.geminiAccountId=r),class:"form-input w-full",disabled:l.permissions==="claude"},[o[69]||(o[69]=e("option",{value:""}," 使用共享账号池 ",-1)),b.value.geminiGroups&&b.value.geminiGroups.length>0?(n(),i("optgroup",zt,[(n(!0),i(R,null,G(b.value.geminiGroups,r=>(n(),i("option",{key:`group:${r.id}`,value:`group:${r.id}`},u(r.name)+" ("+u(r.memberCount||0)+" 个成员) ",9,Nt))),128))])):y("",!0),b.value.gemini.filter(r=>r.accountType==="dedicated").length>0?(n(),i("optgroup",Yt,[(n(!0),i(R,null,G(b.value.gemini.filter(r=>r.accountType==="dedicated"),r=>(n(),i("option",{key:r.id,value:r.id},u(r.name)+" ("+u(r.status==="active"?"正常":"异常")+") ",9,Bt))),128))])):y("",!0)],8,Wt),[[le,l.geminiAccountId]])])]),o[71]||(o[71]=e("p",{class:"text-xs text-gray-500 mt-2"}," 选择专属账号后,此API Key将只使用该账号,不选择则使用共享账号池 ",-1))]),e("div",null,[e("div",Ht,[D(e("input",{id:"enableModelRestriction","onUpdate:modelValue":o[24]||(o[24]=r=>l.enableModelRestriction=r),type:"checkbox",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[de,l.enableModelRestriction]]),o[72]||(o[72]=e("label",{for:"enableModelRestriction",class:"ml-2 text-sm font-semibold text-gray-700 cursor-pointer"}," 启用模型限制 ",-1))]),l.enableModelRestriction?(n(),i("div",Qt,[e("div",null,[o[75]||(o[75]=e("label",{class:"block text-xs font-medium text-gray-700 mb-1"},"限制的模型列表",-1)),e("div",Xt,[(n(!0),i(R,null,G(l.restrictedModels,(r,F)=>(n(),i("span",{key:F,class:"inline-flex items-center px-2 py-1 rounded-full text-xs bg-red-100 text-red-800"},[h(u(r)+" ",1),e("button",{type:"button",class:"ml-1 text-red-600 hover:text-red-800",onClick:Q=>T(F)},o[73]||(o[73]=[e("i",{class:"fas fa-times text-xs"},null,-1)]),8,Jt)]))),128)),l.restrictedModels.length===0?(n(),i("span",Zt," 暂无限制的模型 ")):y("",!0)]),e("div",es,[D(e("input",{"onUpdate:modelValue":o[25]||(o[25]=r=>l.modelInput=r),type:"text",placeholder:"输入模型名称,按回车添加",class:"form-input flex-1 text-sm",onKeydown:ye(ie(H,["prevent"]),["enter"])},null,40,ts),[[z,l.modelInput]]),e("button",{type:"button",class:"px-3 py-1.5 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors text-sm",onClick:H},o[74]||(o[74]=[e("i",{class:"fas fa-plus"},null,-1)]))]),o[76]||(o[76]=e("p",{class:"text-xs text-gray-500 mt-1"}," 例如:claude-opus-4-20250514 ",-1))])])):y("",!0)]),e("div",null,[e("div",ss,[D(e("input",{id:"enableClientRestriction","onUpdate:modelValue":o[26]||(o[26]=r=>l.enableClientRestriction=r),type:"checkbox",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[de,l.enableClientRestriction]]),o[77]||(o[77]=e("label",{for:"enableClientRestriction",class:"ml-2 text-sm font-semibold text-gray-700 cursor-pointer"}," 启用客户端限制 ",-1))]),l.enableClientRestriction?(n(),i("div",ls,[e("div",null,[o[78]||(o[78]=e("label",{class:"block text-xs font-medium text-gray-700 mb-2"},"允许的客户端",-1)),e("div",os,[(n(!0),i(R,null,G(d.value,r=>(n(),i("div",{key:r.id,class:"flex items-start"},[D(e("input",{id:`client_${r.id}`,"onUpdate:modelValue":o[27]||(o[27]=F=>l.allowedClients=F),type:"checkbox",value:r.id,class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 mt-0.5"},null,8,ns),[[de,l.allowedClients]]),e("label",{for:`client_${r.id}`,class:"ml-2 flex-1 cursor-pointer"},[e("span",as,u(r.name),1),e("span",rs,u(r.description),1)],8,is)]))),128))])])])):y("",!0)]),e("div",ds,[e("button",{type:"button",class:"flex-1 px-4 py-2.5 bg-gray-100 text-gray-700 rounded-lg font-semibold hover:bg-gray-200 transition-colors text-sm",onClick:o[28]||(o[28]=r=>_.$emit("close"))}," 取消 "),e("button",{type:"submit",disabled:$.value,class:"btn btn-primary flex-1 py-2.5 px-4 font-semibold text-sm"},[$.value?(n(),i("div",cs)):(n(),i("i",ms)),h(" "+u($.value?"创建中...":"创建"),1)],8,us)])],32)])])]))}},xs=ae(ps,[["__scopeId","data-v-627c6d2b"]]),gs={class:"fixed inset-0 modal z-50 flex items-center justify-center p-3 sm:p-4"},fs={class:"modal-content w-full max-w-4xl p-4 sm:p-6 md:p-8 mx-auto max-h-[90vh] flex flex-col"},ys={class:"flex items-center justify-between mb-4 sm:mb-6"},bs=["value"],vs={class:"space-y-4"},ws={key:0},$s={class:"flex flex-wrap gap-2"},hs=["onClick"],As={key:1},Cs={class:"flex flex-wrap gap-2"},Ks=["onClick"],ks={class:"flex gap-2"},_s=["onKeypress"],Ds={class:"bg-blue-50 border border-blue-200 rounded-lg p-3"},Is={class:"space-y-2"},Ls={class:"grid grid-cols-1 lg:grid-cols-3 gap-2"},Ts={class:"space-y-3"},Ms={class:"flex gap-2"},Ss={class:"flex gap-4"},js={class:"flex items-center cursor-pointer"},Rs={class:"flex items-center cursor-pointer"},Es={class:"flex items-center cursor-pointer"},Ps={class:"flex items-center justify-between mb-3"},Us=["disabled"],Vs={class:"grid grid-cols-1 gap-3"},Gs=["disabled"],Os={key:0,label:"调度分组"},qs=["value"],Fs={key:1,label:"Claude OAuth 专属账号"},Ws=["value"],zs={key:2,label:"Claude Console 专属账号"},Ns=["value"],Ys=["disabled"],Bs={key:0,label:"调度分组"},Hs=["value"],Qs={key:1,label:"Gemini 专属账号"},Xs=["value"],Js={class:"flex items-center mb-3"},Zs={key:0,class:"space-y-3"},el={class:"flex flex-wrap gap-2 mb-3 min-h-[32px] p-2 bg-gray-50 rounded-lg border border-gray-200"},tl=["onClick"],sl={key:0,class:"text-gray-400 text-sm"},ll={class:"flex gap-2"},ol=["onKeydown"],nl={class:"flex items-center mb-3"},il={key:0,class:"space-y-3"},al={class:"space-y-2"},rl=["id","value"],dl=["for"],ul={class:"text-sm font-medium text-gray-700"},cl={class:"text-xs text-gray-500 block"},ml={class:"flex gap-3 pt-4"},pl=["disabled"],xl={key:0,class:"loading-spinner mr-2"},gl={key:1,class:"fas fa-save mr-2"},fl={__name:"EditApiKeyModal",props:{apiKey:{type:Object,required:!0},accounts:{type:Object,default:()=>({claude:[],gemini:[]})}},emits:["close","success"],setup(I,{emit:V}){const f=I,M=V;Re();const j=Ae(),C=Ee(),$=K(!1),O=K(!1),b=K({claude:[],gemini:[],claudeGroups:[],geminiGroups:[]}),q=K([]),L=K(""),w=K([]),k=ee(()=>w.value.filter(T=>!d.tags.includes(T))),d=be({name:"",tokenLimit:"",rateLimitWindow:"",rateLimitRequests:"",concurrencyLimit:"",dailyCostLimit:"",permissions:"all",claudeAccountId:"",geminiAccountId:"",enableModelRestriction:!1,restrictedModels:[],modelInput:"",enableClientRestriction:!1,allowedClients:[],tags:[]}),l=()=>{d.modelInput&&!d.restrictedModels.includes(d.modelInput)&&(d.restrictedModels.push(d.modelInput),d.modelInput="")},N=T=>{d.restrictedModels.splice(T,1)},A=()=>{if(L.value&&L.value.trim()){const T=L.value.trim();d.tags.includes(T)||d.tags.push(T),L.value=""}},x=T=>{d.tags.includes(T)||d.tags.push(T)},p=T=>{d.tags.splice(T,1)},Y=async()=>{$.value=!0;try{const T={tokenLimit:d.tokenLimit!==""&&d.tokenLimit!==null?parseInt(d.tokenLimit):0,rateLimitWindow:d.rateLimitWindow!==""&&d.rateLimitWindow!==null?parseInt(d.rateLimitWindow):0,rateLimitRequests:d.rateLimitRequests!==""&&d.rateLimitRequests!==null?parseInt(d.rateLimitRequests):0,concurrencyLimit:d.concurrencyLimit!==""&&d.concurrencyLimit!==null?parseInt(d.concurrencyLimit):0,dailyCostLimit:d.dailyCostLimit!==""&&d.dailyCostLimit!==null?parseFloat(d.dailyCostLimit):0,permissions:d.permissions,claudeAccountId:d.claudeAccountId||null,geminiAccountId:d.geminiAccountId||null,tags:d.tags};T.enableModelRestriction=d.enableModelRestriction,T.restrictedModels=d.restrictedModels,T.enableClientRestriction=d.enableClientRestriction,T.allowedClients=d.allowedClients;const a=await U.put(`/admin/api-keys/${f.apiKey.id}`,T);a.success?(M("success"),M("close")):S(a.message||"更新失败","error")}catch{S("更新失败","error")}finally{$.value=!1}},H=async()=>{var T,a;O.value=!0;try{const[m,B,te,_]=await Promise.all([U.get("/admin/claude-accounts"),U.get("/admin/claude-console-accounts"),U.get("/admin/gemini-accounts"),U.get("/admin/account-groups")]),o=[];if(m.success&&((T=m.data)==null||T.forEach(r=>{o.push({...r,platform:"claude-oauth",isDedicated:r.accountType==="dedicated"})})),B.success&&((a=B.data)==null||a.forEach(r=>{o.push({...r,platform:"claude-console",isDedicated:r.accountType==="dedicated"})})),b.value.claude=o,te.success&&(b.value.gemini=(te.data||[]).map(r=>({...r,isDedicated:r.accountType==="dedicated"}))),_.success){const r=_.data||[];b.value.claudeGroups=r.filter(F=>F.platform==="claude"),b.value.geminiGroups=r.filter(F=>F.platform==="gemini")}S("账号列表已刷新","success")}catch{S("刷新账号列表失败","error")}finally{O.value=!1}};return he(async()=>{q.value=await j.loadSupportedClients(),w.value=await C.fetchTags(),f.accounts&&(b.value={claude:f.accounts.claude||[],gemini:f.accounts.gemini||[],claudeGroups:f.accounts.claudeGroups||[],geminiGroups:f.accounts.geminiGroups||[]}),d.name=f.apiKey.name,d.tokenLimit=f.apiKey.tokenLimit||"",d.rateLimitWindow=f.apiKey.rateLimitWindow||"",d.rateLimitRequests=f.apiKey.rateLimitRequests||"",d.concurrencyLimit=f.apiKey.concurrencyLimit||"",d.dailyCostLimit=f.apiKey.dailyCostLimit||"",d.permissions=f.apiKey.permissions||"all",d.claudeAccountId=f.apiKey.claudeAccountId||"",d.geminiAccountId=f.apiKey.geminiAccountId||"",d.restrictedModels=f.apiKey.restrictedModels||[],d.allowedClients=f.apiKey.allowedClients||[],d.tags=f.apiKey.tags||[],d.enableModelRestriction=f.apiKey.enableModelRestriction||!1,d.enableClientRestriction=f.apiKey.enableClientRestriction||!1}),(T,a)=>(n(),Z(ue,{to:"body"},[e("div",gs,[e("div",fs,[e("div",ys,[a[22]||(a[22]=e("div",{class:"flex items-center gap-2 sm:gap-3"},[e("div",{class:"w-8 h-8 sm:w-10 sm:h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg sm:rounded-xl flex items-center justify-center"},[e("i",{class:"fas fa-edit text-white text-sm sm:text-base"})]),e("h3",{class:"text-lg sm:text-xl font-bold text-gray-900"}," 编辑 API Key ")],-1)),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors p-1",onClick:a[0]||(a[0]=m=>T.$emit("close"))},a[21]||(a[21]=[e("i",{class:"fas fa-times text-lg sm:text-xl"},null,-1)]))]),e("form",{class:"space-y-4 sm:space-y-6 modal-scroll-content custom-scrollbar flex-1",onSubmit:ie(Y,["prevent"])},[e("div",null,[a[23]||(a[23]=e("label",{class:"block text-xs sm:text-sm font-semibold text-gray-700 mb-1.5 sm:mb-3"},"名称",-1)),e("input",{value:d.name,type:"text",disabled:"",class:"form-input w-full bg-gray-100 cursor-not-allowed text-sm"},null,8,bs),a[24]||(a[24]=e("p",{class:"text-xs text-gray-500 mt-1 sm:mt-2"}," 名称不可修改 ",-1))]),e("div",null,[a[32]||(a[32]=e("label",{class:"block text-xs sm:text-sm font-semibold text-gray-700 mb-1.5 sm:mb-3"},"标签",-1)),e("div",vs,[d.tags.length>0?(n(),i("div",ws,[a[26]||(a[26]=e("div",{class:"text-xs font-medium text-gray-600 mb-2"}," 已选择的标签: ",-1)),e("div",$s,[(n(!0),i(R,null,G(d.tags,(m,B)=>(n(),i("span",{key:"selected-"+B,class:"inline-flex items-center gap-1 px-3 py-1 bg-blue-100 text-blue-800 text-sm rounded-full"},[h(u(m)+" ",1),e("button",{type:"button",class:"ml-1 hover:text-blue-900",onClick:te=>p(B)},a[25]||(a[25]=[e("i",{class:"fas fa-times text-xs"},null,-1)]),8,hs)]))),128))])])):y("",!0),k.value.length>0?(n(),i("div",As,[a[28]||(a[28]=e("div",{class:"text-xs font-medium text-gray-600 mb-2"}," 点击选择已有标签: ",-1)),e("div",Cs,[(n(!0),i(R,null,G(k.value,m=>(n(),i("button",{key:"available-"+m,type:"button",class:"inline-flex items-center gap-1 px-3 py-1 bg-gray-100 text-gray-700 text-sm rounded-full hover:bg-blue-100 hover:text-blue-700 transition-colors",onClick:B=>x(m)},[a[27]||(a[27]=e("i",{class:"fas fa-tag text-gray-500 text-xs"},null,-1)),h(" "+u(m),1)],8,Ks))),128))])])):y("",!0),e("div",null,[a[30]||(a[30]=e("div",{class:"text-xs font-medium text-gray-600 mb-2"}," 创建新标签: ",-1)),e("div",ks,[D(e("input",{"onUpdate:modelValue":a[1]||(a[1]=m=>L.value=m),type:"text",class:"form-input flex-1",placeholder:"输入新标签名称",onKeypress:ye(ie(A,["prevent"]),["enter"])},null,40,_s),[[z,L.value]]),e("button",{type:"button",class:"px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors",onClick:A},a[29]||(a[29]=[e("i",{class:"fas fa-plus"},null,-1)]))])]),a[31]||(a[31]=e("p",{class:"text-xs text-gray-500"}," 用于标记不同团队或用途,方便筛选管理 ",-1))])]),e("div",Ds,[a[40]||(a[40]=e("div",{class:"flex items-center gap-2 mb-2"},[e("div",{class:"w-6 h-6 bg-blue-500 rounded flex items-center justify-center flex-shrink-0"},[e("i",{class:"fas fa-tachometer-alt text-white text-xs"})]),e("h4",{class:"font-semibold text-gray-800 text-sm"}," 速率限制设置 (可选) ")],-1)),e("div",Is,[e("div",Ls,[e("div",null,[a[33]||(a[33]=e("label",{class:"block text-xs font-medium text-gray-700 mb-1"},"时间窗口 (分钟)",-1)),D(e("input",{"onUpdate:modelValue":a[2]||(a[2]=m=>d.rateLimitWindow=m),type:"number",min:"1",placeholder:"无限制",class:"form-input w-full text-sm"},null,512),[[z,d.rateLimitWindow]]),a[34]||(a[34]=e("p",{class:"text-xs text-gray-500 mt-0.5 ml-2"}," 时间段单位 ",-1))]),e("div",null,[a[35]||(a[35]=e("label",{class:"block text-xs font-medium text-gray-700 mb-1"},"请求次数限制",-1)),D(e("input",{"onUpdate:modelValue":a[3]||(a[3]=m=>d.rateLimitRequests=m),type:"number",min:"1",placeholder:"无限制",class:"form-input w-full text-sm"},null,512),[[z,d.rateLimitRequests]]),a[36]||(a[36]=e("p",{class:"text-xs text-gray-500 mt-0.5 ml-2"}," 窗口内最大请求 ",-1))]),e("div",null,[a[37]||(a[37]=e("label",{class:"block text-xs font-medium text-gray-700 mb-1"},"Token 限制",-1)),D(e("input",{"onUpdate:modelValue":a[4]||(a[4]=m=>d.tokenLimit=m),type:"number",placeholder:"无限制",class:"form-input w-full text-sm"},null,512),[[z,d.tokenLimit]]),a[38]||(a[38]=e("p",{class:"text-xs text-gray-500 mt-0.5 ml-2"}," 窗口内最大Token ",-1))])]),a[39]||(a[39]=e("div",{class:"bg-blue-100 rounded-lg p-2"},[e("h5",{class:"text-xs font-semibold text-blue-800 mb-1"}," 💡 使用示例 "),e("div",{class:"text-xs text-blue-700 space-y-0.5"},[e("div",null,[e("strong",null,"示例1:"),h(" 时间窗口=60,请求次数=1000 → 每60分钟最多1000次请求")]),e("div",null,[e("strong",null,"示例2:"),h(" 时间窗口=1,Token=10000 → 每分钟最多10,000个Token")]),e("div",null,[e("strong",null,"示例3:"),h(" 窗口=30,请求=50,Token=100000 → 每30分钟50次请求且不超10万Token")])])],-1))])]),e("div",null,[a[42]||(a[42]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"每日费用限制 (美元)",-1)),e("div",Ts,[e("div",Ms,[e("button",{type:"button",class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium",onClick:a[5]||(a[5]=m=>d.dailyCostLimit="50")}," $50 "),e("button",{type:"button",class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium",onClick:a[6]||(a[6]=m=>d.dailyCostLimit="100")}," $100 "),e("button",{type:"button",class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium",onClick:a[7]||(a[7]=m=>d.dailyCostLimit="200")}," $200 "),e("button",{type:"button",class:"px-3 py-1 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm font-medium",onClick:a[8]||(a[8]=m=>d.dailyCostLimit="")}," 自定义 ")]),D(e("input",{"onUpdate:modelValue":a[9]||(a[9]=m=>d.dailyCostLimit=m),type:"number",min:"0",step:"0.01",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[z,d.dailyCostLimit]]),a[41]||(a[41]=e("p",{class:"text-xs text-gray-500"}," 设置此 API Key 每日的费用限制,超过限制将拒绝请求,0 或留空表示无限制 ",-1))])]),e("div",null,[a[43]||(a[43]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"并发限制",-1)),D(e("input",{"onUpdate:modelValue":a[10]||(a[10]=m=>d.concurrencyLimit=m),type:"number",min:"0",placeholder:"0 表示无限制",class:"form-input w-full"},null,512),[[z,d.concurrencyLimit]]),a[44]||(a[44]=e("p",{class:"text-xs text-gray-500 mt-2"}," 设置此 API Key 可同时处理的最大请求数 ",-1))]),e("div",null,[a[48]||(a[48]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"服务权限",-1)),e("div",Ss,[e("label",js,[D(e("input",{"onUpdate:modelValue":a[11]||(a[11]=m=>d.permissions=m),type:"radio",value:"all",class:"mr-2"},null,512),[[ne,d.permissions]]),a[45]||(a[45]=e("span",{class:"text-sm text-gray-700"},"全部服务",-1))]),e("label",Rs,[D(e("input",{"onUpdate:modelValue":a[12]||(a[12]=m=>d.permissions=m),type:"radio",value:"claude",class:"mr-2"},null,512),[[ne,d.permissions]]),a[46]||(a[46]=e("span",{class:"text-sm text-gray-700"},"仅 Claude",-1))]),e("label",Es,[D(e("input",{"onUpdate:modelValue":a[13]||(a[13]=m=>d.permissions=m),type:"radio",value:"gemini",class:"mr-2"},null,512),[[ne,d.permissions]]),a[47]||(a[47]=e("span",{class:"text-sm text-gray-700"},"仅 Gemini",-1))])]),a[49]||(a[49]=e("p",{class:"text-xs text-gray-500 mt-2"}," 控制此 API Key 可以访问哪些服务 ",-1))]),e("div",null,[e("div",Ps,[a[50]||(a[50]=e("label",{class:"text-sm font-semibold text-gray-700"},"专属账号绑定",-1)),e("button",{type:"button",class:"text-blue-600 hover:text-blue-800 text-sm flex items-center gap-1 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",title:"刷新账号列表",disabled:O.value,onClick:H},[e("i",{class:P(["fas",O.value?"fa-spinner fa-spin":"fa-sync-alt","text-xs"])},null,2),e("span",null,u(O.value?"刷新中...":"刷新账号"),1)],8,Us)]),e("div",Vs,[e("div",null,[a[52]||(a[52]=e("label",{class:"block text-sm font-medium text-gray-600 mb-1"},"Claude 专属账号",-1)),D(e("select",{"onUpdate:modelValue":a[14]||(a[14]=m=>d.claudeAccountId=m),class:"form-input w-full",disabled:d.permissions==="gemini"},[a[51]||(a[51]=e("option",{value:""}," 使用共享账号池 ",-1)),b.value.claudeGroups&&b.value.claudeGroups.length>0?(n(),i("optgroup",Os,[(n(!0),i(R,null,G(b.value.claudeGroups,m=>(n(),i("option",{key:`group:${m.id}`,value:`group:${m.id}`},u(m.name)+" ("+u(m.memberCount||0)+" 个成员) ",9,qs))),128))])):y("",!0),b.value.claude.filter(m=>m.accountType==="dedicated"&&m.platform==="claude-oauth").length>0?(n(),i("optgroup",Fs,[(n(!0),i(R,null,G(b.value.claude.filter(m=>m.accountType==="dedicated"&&m.platform==="claude-oauth"),m=>(n(),i("option",{key:m.id,value:m.id},u(m.name)+" ("+u(m.status==="active"?"正常":"异常")+") ",9,Ws))),128))])):y("",!0),b.value.claude.filter(m=>m.accountType==="dedicated"&&m.platform==="claude-console").length>0?(n(),i("optgroup",zs,[(n(!0),i(R,null,G(b.value.claude.filter(m=>m.accountType==="dedicated"&&m.platform==="claude-console"),m=>(n(),i("option",{key:m.id,value:`console:${m.id}`},u(m.name)+" ("+u(m.status==="active"?"正常":"异常")+") ",9,Ns))),128))])):y("",!0)],8,Gs),[[le,d.claudeAccountId]])]),e("div",null,[a[54]||(a[54]=e("label",{class:"block text-sm font-medium text-gray-600 mb-1"},"Gemini 专属账号",-1)),D(e("select",{"onUpdate:modelValue":a[15]||(a[15]=m=>d.geminiAccountId=m),class:"form-input w-full",disabled:d.permissions==="claude"},[a[53]||(a[53]=e("option",{value:""}," 使用共享账号池 ",-1)),b.value.geminiGroups&&b.value.geminiGroups.length>0?(n(),i("optgroup",Bs,[(n(!0),i(R,null,G(b.value.geminiGroups,m=>(n(),i("option",{key:`group:${m.id}`,value:`group:${m.id}`},u(m.name)+" ("+u(m.memberCount||0)+" 个成员) ",9,Hs))),128))])):y("",!0),b.value.gemini.filter(m=>m.accountType==="dedicated").length>0?(n(),i("optgroup",Qs,[(n(!0),i(R,null,G(b.value.gemini.filter(m=>m.accountType==="dedicated"),m=>(n(),i("option",{key:m.id,value:m.id},u(m.name)+" ("+u(m.status==="active"?"正常":"异常")+") ",9,Xs))),128))])):y("",!0)],8,Ys),[[le,d.geminiAccountId]])])]),a[55]||(a[55]=e("p",{class:"text-xs text-gray-500 mt-2"}," 修改绑定账号将影响此API Key的请求路由 ",-1))]),e("div",null,[e("div",Js,[D(e("input",{id:"editEnableModelRestriction","onUpdate:modelValue":a[16]||(a[16]=m=>d.enableModelRestriction=m),type:"checkbox",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[de,d.enableModelRestriction]]),a[56]||(a[56]=e("label",{for:"editEnableModelRestriction",class:"ml-2 text-sm font-semibold text-gray-700 cursor-pointer"}," 启用模型限制 ",-1))]),d.enableModelRestriction?(n(),i("div",Zs,[e("div",null,[a[59]||(a[59]=e("label",{class:"block text-sm font-medium text-gray-600 mb-2"},"限制的模型列表",-1)),e("div",el,[(n(!0),i(R,null,G(d.restrictedModels,(m,B)=>(n(),i("span",{key:B,class:"inline-flex items-center px-3 py-1 rounded-full text-sm bg-red-100 text-red-800"},[h(u(m)+" ",1),e("button",{type:"button",class:"ml-2 text-red-600 hover:text-red-800",onClick:te=>N(B)},a[57]||(a[57]=[e("i",{class:"fas fa-times text-xs"},null,-1)]),8,tl)]))),128)),d.restrictedModels.length===0?(n(),i("span",sl," 暂无限制的模型 ")):y("",!0)]),e("div",ll,[D(e("input",{"onUpdate:modelValue":a[17]||(a[17]=m=>d.modelInput=m),type:"text",placeholder:"输入模型名称,按回车添加",class:"form-input flex-1",onKeydown:ye(ie(l,["prevent"]),["enter"])},null,40,ol),[[z,d.modelInput]]),e("button",{type:"button",class:"px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors",onClick:l},a[58]||(a[58]=[e("i",{class:"fas fa-plus"},null,-1)]))]),a[60]||(a[60]=e("p",{class:"text-xs text-gray-500 mt-2"}," 设置此API Key无法访问的模型,例如:claude-opus-4-20250514 ",-1))])])):y("",!0)]),e("div",null,[e("div",nl,[D(e("input",{id:"editEnableClientRestriction","onUpdate:modelValue":a[18]||(a[18]=m=>d.enableClientRestriction=m),type:"checkbox",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[de,d.enableClientRestriction]]),a[61]||(a[61]=e("label",{for:"editEnableClientRestriction",class:"ml-2 text-sm font-semibold text-gray-700 cursor-pointer"}," 启用客户端限制 ",-1))]),d.enableClientRestriction?(n(),i("div",il,[e("div",null,[a[62]||(a[62]=e("label",{class:"block text-sm font-medium text-gray-600 mb-2"},"允许的客户端",-1)),a[63]||(a[63]=e("p",{class:"text-xs text-gray-500 mb-3"}," 勾选允许使用此API Key的客户端 ",-1)),e("div",al,[(n(!0),i(R,null,G(q.value,m=>(n(),i("div",{key:m.id,class:"flex items-start"},[D(e("input",{id:`edit_client_${m.id}`,"onUpdate:modelValue":a[19]||(a[19]=B=>d.allowedClients=B),type:"checkbox",value:m.id,class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 mt-0.5"},null,8,rl),[[de,d.allowedClients]]),e("label",{for:`edit_client_${m.id}`,class:"ml-2 flex-1 cursor-pointer"},[e("span",ul,u(m.name),1),e("span",cl,u(m.description),1)],8,dl)]))),128))])])])):y("",!0)]),e("div",ml,[e("button",{type:"button",class:"flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors",onClick:a[20]||(a[20]=m=>T.$emit("close"))}," 取消 "),e("button",{type:"submit",disabled:$.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold"},[$.value?(n(),i("div",xl)):(n(),i("i",gl)),h(" "+u($.value?"保存中...":"保存修改"),1)],8,pl)])],32)])])]))}},yl=ae(fl,[["__scopeId","data-v-12fe4aaf"]]),bl={class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},vl={class:"modal-content w-full max-w-md p-8 mx-auto max-h-[90vh] flex flex-col"},wl={class:"flex items-center justify-between mb-6"},$l={class:"space-y-6 modal-scroll-content custom-scrollbar flex-1"},hl={class:"bg-blue-50 border border-blue-200 rounded-lg p-4"},Al={class:"flex items-start gap-3"},Cl={class:"text-sm text-gray-700"},Kl={class:"text-xs text-gray-600 mt-1"},kl={key:0,class:"mt-3"},_l=["min"],Dl={key:1,class:"text-xs text-gray-500 mt-2"},Il={class:"flex gap-3 pt-4"},Ll=["disabled"],Tl={key:0,class:"loading-spinner mr-2"},Ml={key:1,class:"fas fa-clock mr-2"},Sl={__name:"RenewApiKeyModal",props:{apiKey:{type:Object,required:!0}},emits:["close","success"],setup(I,{emit:V}){const f=I,M=V;Re();const j=K(!1),C=be({renewDuration:"30d",customExpireDate:"",newExpiresAt:null}),$=ee(()=>{const w=new Date;return f.apiKey.expiresAt&&new Date(f.apiKey.expiresAt)>w?new Date(f.apiKey.expiresAt).toISOString().slice(0,16):(w.setMinutes(w.getMinutes()+1),w.toISOString().slice(0,16))}),O=w=>new Date(w).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}),b=()=>{if(!C.renewDuration){C.newExpiresAt=null;return}if(C.renewDuration==="permanent"){C.newExpiresAt=null;return}if(C.renewDuration==="custom")return;const w=f.apiKey.expiresAt&&new Date(f.apiKey.expiresAt)>new Date?new Date(f.apiKey.expiresAt):new Date,d=C.renewDuration.match(/(\d+)([dhmy])/);if(d){const[,l,N]=d,A=parseInt(l);switch(N){case"d":w.setDate(w.getDate()+A);break;case"h":w.setHours(w.getHours()+A);break;case"m":w.setMonth(w.getMonth()+A);break;case"y":w.setFullYear(w.getFullYear()+A);break}C.newExpiresAt=w.toISOString()}},q=()=>{C.customExpireDate&&(C.newExpiresAt=new Date(C.customExpireDate).toISOString())},L=async()=>{j.value=!0;try{const w={expiresAt:C.renewDuration==="permanent"?null:C.newExpiresAt},k=await U.put(`/admin/api-keys/${f.apiKey.id}/renew`,w);k.success?(S("API Key 续期成功","success"),M("success"),M("close")):S(k.message||"续期失败","error")}catch{S("续期失败","error")}finally{j.value=!1}};return b(),(w,k)=>(n(),Z(ue,{to:"body"},[e("div",bl,[e("div",vl,[e("div",wl,[k[5]||(k[5]=e("div",{class:"flex items-center gap-3"},[e("div",{class:"w-10 h-10 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center"},[e("i",{class:"fas fa-clock text-white"})]),e("h3",{class:"text-xl font-bold text-gray-900"}," 续期 API Key ")],-1)),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors",onClick:k[0]||(k[0]=d=>w.$emit("close"))},k[4]||(k[4]=[e("i",{class:"fas fa-times text-xl"},null,-1)]))]),e("div",$l,[e("div",hl,[e("div",Al,[k[7]||(k[7]=e("div",{class:"w-8 h-8 bg-blue-500 rounded-lg flex items-center justify-center flex-shrink-0"},[e("i",{class:"fas fa-info text-white text-sm"})],-1)),e("div",null,[k[6]||(k[6]=e("h4",{class:"font-semibold text-gray-800 mb-1"}," API Key 信息 ",-1)),e("p",Cl,u(I.apiKey.name),1),e("p",Kl," 当前过期时间:"+u(I.apiKey.expiresAt?O(I.apiKey.expiresAt):"永不过期"),1)])])]),e("div",null,[k[9]||(k[9]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"续期时长",-1)),D(e("select",{"onUpdate:modelValue":k[1]||(k[1]=d=>C.renewDuration=d),class:"form-input w-full",onChange:b},k[8]||(k[8]=[e("option",{value:"7d"}," 延长 7 天 ",-1),e("option",{value:"30d"}," 延长 30 天 ",-1),e("option",{value:"90d"}," 延长 90 天 ",-1),e("option",{value:"180d"}," 延长 180 天 ",-1),e("option",{value:"365d"}," 延长 365 天 ",-1),e("option",{value:"custom"}," 自定义日期 ",-1),e("option",{value:"permanent"}," 设为永不过期 ",-1)]),544),[[le,C.renewDuration]]),C.renewDuration==="custom"?(n(),i("div",kl,[D(e("input",{"onUpdate:modelValue":k[2]||(k[2]=d=>C.customExpireDate=d),type:"datetime-local",class:"form-input w-full",min:$.value,onChange:q},null,40,_l),[[z,C.customExpireDate]])])):y("",!0),C.newExpiresAt?(n(),i("p",Dl," 新的过期时间:"+u(O(C.newExpiresAt)),1)):y("",!0)])]),e("div",Il,[e("button",{type:"button",class:"flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors",onClick:k[3]||(k[3]=d=>w.$emit("close"))}," 取消 "),e("button",{type:"button",disabled:j.value||!C.renewDuration,class:"btn btn-primary flex-1 py-3 px-6 font-semibold",onClick:L},[j.value?(n(),i("div",Tl)):(n(),i("i",Ml)),h(" "+u(j.value?"续期中...":"确认续期"),1)],8,Ll)])])])]))}},jl=ae(Sl,[["__scopeId","data-v-0c3b1b3f"]]),Rl={class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},El={class:"modal-content w-full max-w-lg p-8 mx-auto max-h-[90vh] overflow-y-auto custom-scrollbar"},Pl={class:"space-y-4 mb-6"},Ul={class:"p-3 bg-gray-50 rounded-lg border"},Vl={class:"text-gray-900 font-medium"},Gl={key:0},Ol={class:"p-3 bg-gray-50 rounded-lg border"},ql={class:"text-gray-700"},Fl={class:"relative"},Wl={class:"p-4 pr-14 bg-gray-900 rounded-lg border font-mono text-sm text-white break-all min-h-[60px] flex items-center"},zl={class:"absolute top-3 right-3"},Nl=["title"],Yl={__name:"NewApiKeyModal",props:{apiKey:{type:Object,required:!0}},emits:["close"],setup(I,{emit:V}){const f=I,M=V,j=K(!1),C=()=>{j.value=!j.value},$=()=>{const L=f.apiKey.apiKey||f.apiKey.key||"";return L?j.value||L.length<=12?L:L.substring(0,8)+"●".repeat(Math.max(0,L.length-12))+L.substring(L.length-4):""},O=async()=>{const L=f.apiKey.apiKey||f.apiKey.key||"";if(!L){S("API Key 不存在","error");return}try{await navigator.clipboard.writeText(L),S("API Key 已复制到剪贴板","success")}catch(w){console.error("Failed to copy:",w);const k=document.createElement("textarea");k.value=L,document.body.appendChild(k),k.select();try{document.execCommand("copy"),S("API Key 已复制到剪贴板","success")}catch{S("复制失败,请手动复制","error")}finally{document.body.removeChild(k)}}},b=async()=>{window.showConfirm?await window.showConfirm("关闭提醒",`关闭后将无法再次查看完整的API Key,请确保已经妥善保存。
|
||
|
||
确定要关闭吗?`,"确定关闭","取消")&&M("close"):confirm(`关闭后将无法再次查看完整的API Key,请确保已经妥善保存。
|
||
|
||
确定要关闭吗?`)&&M("close")},q=async()=>{window.showConfirm?await window.showConfirm("确定要关闭吗?",`您还没有保存API Key,关闭后将无法再次查看。
|
||
|
||
建议您先复制API Key再关闭。`,"仍然关闭","返回复制")&&M("close"):confirm(`您还没有保存API Key,关闭后将无法再次查看。
|
||
|
||
确定要关闭吗?`)&&M("close")};return(L,w)=>(n(),Z(ue,{to:"body"},[e("div",Rl,[e("div",El,[e("div",{class:"flex items-center justify-between mb-6"},[w[1]||(w[1]=e("div",{class:"flex items-center gap-3"},[e("div",{class:"w-12 h-12 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center"},[e("i",{class:"fas fa-check text-white text-lg"})]),e("div",null,[e("h3",{class:"text-xl font-bold text-gray-900"}," API Key 创建成功 "),e("p",{class:"text-sm text-gray-600"}," 请妥善保存您的 API Key ")])],-1)),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors",title:"直接关闭(不推荐)",onClick:q},w[0]||(w[0]=[e("i",{class:"fas fa-times text-xl"},null,-1)]))]),w[7]||(w[7]=e("div",{class:"bg-amber-50 border-l-4 border-amber-400 p-4 mb-6"},[e("div",{class:"flex items-start"},[e("div",{class:"w-6 h-6 bg-amber-400 rounded-lg flex items-center justify-center flex-shrink-0 mt-0.5"},[e("i",{class:"fas fa-exclamation-triangle text-white text-sm"})]),e("div",{class:"ml-3"},[e("h5",{class:"font-semibold text-amber-900 mb-1"}," 重要提醒 "),e("p",{class:"text-sm text-amber-800"}," 这是您唯一能看到完整 API Key 的机会。关闭此窗口后,系统将不再显示完整的 API Key。请立即复制并妥善保存。 ")])])],-1)),e("div",Pl,[e("div",null,[w[2]||(w[2]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"API Key 名称",-1)),e("div",Ul,[e("span",Vl,u(I.apiKey.name),1)])]),I.apiKey.description?(n(),i("div",Gl,[w[3]||(w[3]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"备注",-1)),e("div",Ol,[e("span",ql,u(I.apiKey.description||"无描述"),1)])])):y("",!0),e("div",null,[w[4]||(w[4]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"API Key",-1)),e("div",Fl,[e("div",Wl,u($()),1),e("div",zl,[e("button",{type:"button",class:"btn-icon-sm hover:bg-gray-800 bg-gray-700",title:j.value?"隐藏API Key":"显示完整API Key",onClick:C},[e("i",{class:P(["fas",j.value?"fa-eye-slash":"fa-eye","text-gray-300"])},null,2)],8,Nl)])]),w[5]||(w[5]=e("p",{class:"text-xs text-gray-500 mt-2"}," 点击眼睛图标切换显示模式,使用下方按钮复制完整 API Key ",-1))])]),e("div",{class:"flex gap-3"},[e("button",{class:"flex-1 btn btn-primary py-3 px-6 font-semibold flex items-center justify-center gap-2",onClick:O},w[6]||(w[6]=[e("i",{class:"fas fa-copy"},null,-1),h(" 复制 API Key ",-1)])),e("button",{class:"px-6 py-3 bg-gray-200 text-gray-800 rounded-xl font-semibold hover:bg-gray-300 transition-colors border border-gray-300",onClick:b}," 我已保存 ")])])])]))}},Bl=ae(Yl,[["__scopeId","data-v-2c02f1f7"]]),Hl={class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},Ql={class:"modal-content w-full max-w-2xl p-8 mx-auto max-h-[90vh] overflow-y-auto custom-scrollbar"},Xl={class:"flex items-center justify-between mb-6"},Jl={class:"flex items-center gap-3"},Zl={class:"text-sm text-gray-600"},eo={class:"grid grid-cols-2 md:grid-cols-4 gap-4 mb-6"},to={class:"bg-gradient-to-br from-blue-50 to-blue-100 rounded-lg p-4 border border-blue-200"},so={class:"flex items-center justify-between"},lo={class:"text-2xl font-bold text-blue-900 mt-1"},oo={class:"bg-gradient-to-br from-green-50 to-green-100 rounded-lg p-4 border border-green-200"},no={class:"flex items-center justify-between"},io={class:"text-lg font-bold text-green-900 mt-1 truncate"},ao={class:"bg-gradient-to-br from-purple-50 to-purple-100 rounded-lg p-4 border border-purple-200"},ro={class:"flex items-center justify-between"},uo={class:"text-lg font-bold text-purple-900 mt-1"},co={class:"bg-gradient-to-br from-orange-50 to-orange-100 rounded-lg p-4 border border-orange-200"},mo={class:"flex items-center justify-between"},po={class:"text-lg font-bold text-orange-900 mt-1"},xo={class:"mb-6"},go={class:"flex items-center justify-between mb-3"},fo={class:"flex items-center gap-2"},yo={key:0,class:"bg-gray-900 rounded-lg p-4 max-h-48 overflow-y-auto custom-scrollbar"},bo={class:"text-xs text-gray-300 font-mono"},vo={__name:"BatchApiKeyModal",props:{apiKeys:{type:Array,required:!0}},emits:["close"],setup(I,{emit:V}){const f=I,M=V,j=K(!1),C=ee(()=>{if(f.apiKeys.length>0){const d=f.apiKeys[0],l=d.name.match(/^(.+)_\d+$/);return l?l[1]:d.name}return""}),$=()=>{if(f.apiKeys.length===0)return"未知";const d=f.apiKeys[0].permissions;return{all:"全部服务",claude:"仅 Claude",gemini:"仅 Gemini"}[d]||d},O=()=>{if(f.apiKeys.length===0)return"未知";const d=f.apiKeys[0].expiresAt;if(!d)return"永不过期";const l=new Date(d),A=Math.ceil((l-new Date)/(1e3*60*60*24));return A<=7?`${A}天`:A<=30?`${Math.ceil(A/7)}周`:A<=365?`${Math.ceil(A/30)}个月`:`${Math.ceil(A/365)}年`},b=()=>{j.value=!j.value},q=()=>{const l=f.apiKeys.slice(0,10).map((N,A)=>`${N.name}: ${N.apiKey||N.key||""}`);return f.apiKeys.length>10&&l.push(`... 还有 ${f.apiKeys.length-10} 个 API Key`),l.join(`
|
||
`)},L=()=>{const d=f.apiKeys.map(p=>`${p.name}: ${p.apiKey||p.key||""}`).join(`
|
||
`),l=new Blob([d],{type:"text/plain;charset=utf-8"}),N=URL.createObjectURL(l),A=document.createElement("a");A.href=N;const x=new Date().toISOString().replace(/[:.]/g,"-").slice(0,-5);A.download=`api-keys-${C.value}-${x}.txt`,document.body.appendChild(A),A.click(),document.body.removeChild(A),URL.revokeObjectURL(N),S("API Keys 文件已下载","success")},w=async()=>{window.showConfirm?await window.showConfirm("关闭提醒",`关闭后将无法再次查看这些 API Key,请确保已经下载并妥善保存。
|
||
|
||
确定要关闭吗?`,"确定关闭","返回下载")&&M("close"):confirm(`关闭后将无法再次查看这些 API Key,请确保已经下载并妥善保存。
|
||
|
||
确定要关闭吗?`)&&M("close")},k=async()=>{window.showConfirm?await window.showConfirm("确定要关闭吗?",`您还没有下载 API Keys,关闭后将无法再次查看。
|
||
|
||
强烈建议您先下载保存。`,"仍然关闭","返回下载")&&M("close"):confirm(`您还没有下载 API Keys,关闭后将无法再次查看。
|
||
|
||
确定要关闭吗?`)&&M("close")};return(d,l)=>(n(),Z(ue,{to:"body"},[e("div",Hl,[e("div",Ql,[e("div",Xl,[e("div",Jl,[l[1]||(l[1]=e("div",{class:"w-12 h-12 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center"},[e("i",{class:"fas fa-layer-group text-white text-lg"})],-1)),e("div",null,[l[0]||(l[0]=e("h3",{class:"text-xl font-bold text-gray-900"}," 批量创建成功 ",-1)),e("p",Zl," 成功创建 "+u(I.apiKeys.length)+" 个 API Key ",1)])]),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors",title:"直接关闭(不推荐)",onClick:k},l[2]||(l[2]=[e("i",{class:"fas fa-times text-xl"},null,-1)]))]),l[14]||(l[14]=e("div",{class:"bg-amber-50 border-l-4 border-amber-400 p-4 mb-6"},[e("div",{class:"flex items-start"},[e("div",{class:"w-6 h-6 bg-amber-400 rounded-lg flex items-center justify-center flex-shrink-0 mt-0.5"},[e("i",{class:"fas fa-exclamation-triangle text-white text-sm"})]),e("div",{class:"ml-3"},[e("h5",{class:"font-semibold text-amber-900 mb-1"}," 重要提醒 "),e("p",{class:"text-sm text-amber-800"}," 这是您唯一能看到所有 API Key 的机会。关闭此窗口后,系统将不再显示完整的 API Key。请立即下载并妥善保存。 ")])])],-1)),e("div",eo,[e("div",to,[e("div",so,[e("div",null,[l[3]||(l[3]=e("p",{class:"text-xs text-blue-600 font-medium"}," 创建数量 ",-1)),e("p",lo,u(I.apiKeys.length),1)]),l[4]||(l[4]=e("div",{class:"w-10 h-10 bg-blue-500 bg-opacity-20 rounded-lg flex items-center justify-center"},[e("i",{class:"fas fa-key text-blue-600"})],-1))])]),e("div",oo,[e("div",no,[e("div",null,[l[5]||(l[5]=e("p",{class:"text-xs text-green-600 font-medium"}," 基础名称 ",-1)),e("p",io,u(C.value),1)]),l[6]||(l[6]=e("div",{class:"w-10 h-10 bg-green-500 bg-opacity-20 rounded-lg flex items-center justify-center"},[e("i",{class:"fas fa-tag text-green-600"})],-1))])]),e("div",ao,[e("div",ro,[e("div",null,[l[7]||(l[7]=e("p",{class:"text-xs text-purple-600 font-medium"}," 权限范围 ",-1)),e("p",uo,u($()),1)]),l[8]||(l[8]=e("div",{class:"w-10 h-10 bg-purple-500 bg-opacity-20 rounded-lg flex items-center justify-center"},[e("i",{class:"fas fa-shield-alt text-purple-600"})],-1))])]),e("div",co,[e("div",mo,[e("div",null,[l[9]||(l[9]=e("p",{class:"text-xs text-orange-600 font-medium"}," 过期时间 ",-1)),e("p",po,u(O()),1)]),l[10]||(l[10]=e("div",{class:"w-10 h-10 bg-orange-500 bg-opacity-20 rounded-lg flex items-center justify-center"},[e("i",{class:"fas fa-clock text-orange-600"})],-1))])])]),e("div",xo,[e("div",go,[l[12]||(l[12]=e("label",{class:"text-sm font-semibold text-gray-700"},"API Keys 预览",-1)),e("div",fo,[e("button",{type:"button",class:"text-xs text-blue-600 hover:text-blue-800 flex items-center gap-1",onClick:b},[e("i",{class:P(["fas",j.value?"fa-eye-slash":"fa-eye"])},null,2),h(" "+u(j.value?"隐藏":"显示")+"预览 ",1)]),l[11]||(l[11]=e("span",{class:"text-xs text-gray-500"},"(最多显示前10个)",-1))])]),j.value?(n(),i("div",yo,[e("pre",bo,u(q()),1)])):y("",!0)]),e("div",{class:"flex gap-3"},[e("button",{class:"flex-1 btn btn-primary py-3 px-6 font-semibold flex items-center justify-center gap-2",onClick:L},l[13]||(l[13]=[e("i",{class:"fas fa-download"},null,-1),h(" 下载所有 API Keys ",-1)])),e("button",{class:"px-6 py-3 bg-gray-200 text-gray-800 rounded-xl font-semibold hover:bg-gray-300 transition-colors border border-gray-300",onClick:w}," 我已保存 ")]),l[15]||(l[15]=e("div",{class:"mt-4 p-3 bg-blue-50 rounded-lg border border-blue-200"},[e("p",{class:"text-xs text-blue-700 flex items-start"},[e("i",{class:"fas fa-info-circle mr-2 mt-0.5 flex-shrink-0"}),e("span",null," 下载的文件格式为文本文件(.txt),每行包含一个 API Key。 请将文件保存在安全的位置,避免泄露。 ")])],-1))])])]))}},wo=ae(vo,[["__scopeId","data-v-cff10d08"]]),$o={key:0,class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},ho={class:"modal-content w-full max-w-lg p-8 mx-auto"},Ao={class:"flex items-center justify-between mb-6"},Co={class:"flex items-center gap-3"},Ko={class:"text-sm text-gray-600"},ko={class:"space-y-6"},_o={class:"bg-gradient-to-r from-gray-50 to-gray-100 rounded-lg p-4 border border-gray-200"},Do={class:"flex items-center justify-between"},Io={class:"text-sm font-semibold text-gray-800"},Lo={class:"w-12 h-12 bg-white rounded-lg flex items-center justify-center shadow-sm"},To={class:"grid grid-cols-3 gap-2 mb-3"},Mo=["onClick"],So={key:0,class:"animate-fadeIn"},jo=["min"],Ro={key:1,class:"bg-gradient-to-r from-blue-50 to-indigo-50 rounded-lg p-4 border border-blue-200"},Eo={class:"flex items-center justify-between"},Po={class:"text-sm font-semibold text-blue-900"},Uo={class:"flex gap-3 pt-2"},Vo=["disabled"],Go={key:0,class:"loading-spinner mr-2"},Oo={key:1,class:"fas fa-save mr-2"},qo={__name:"ExpiryEditModal",props:{show:{type:Boolean,required:!0},apiKey:{type:Object,required:!0}},emits:["close","save"],setup(I,{expose:V,emit:f}){const M=I,j=f,C=K(!1),$=be({expireDuration:"",customExpireDate:"",expiresAt:null}),O=[{value:"",label:"永不过期"},{value:"1d",label:"1 天"},{value:"7d",label:"7 天"},{value:"30d",label:"30 天"},{value:"90d",label:"90 天"},{value:"180d",label:"180 天"},{value:"365d",label:"1 年"},{value:"730d",label:"2 年"}],b=ee(()=>{const x=new Date;return x.setMinutes(x.getMinutes()+1),x.toISOString().slice(0,16)});$e(()=>M.show,x=>{x&&q()}),$e(()=>{var x;return(x=M.apiKey)==null?void 0:x.id},x=>{x&&M.show&&q()});const q=()=>{C.value=!1,M.apiKey.expiresAt?($.expireDuration="custom",$.customExpireDate=new Date(M.apiKey.expiresAt).toISOString().slice(0,16),$.expiresAt=M.apiKey.expiresAt):($.expireDuration="",$.customExpireDate="",$.expiresAt=null)},L=x=>{if($.expireDuration=x,!x){$.expiresAt=null;return}if(x==="custom")return;const p=new Date,Y=x.match(/(\d+)([dhmy])/);if(Y){const[,H,T]=Y,a=parseInt(H);switch(T){case"d":p.setDate(p.getDate()+a);break;case"h":p.setHours(p.getHours()+a);break;case"m":p.setMonth(p.getMonth()+a);break;case"y":p.setFullYear(p.getFullYear()+a);break}$.expiresAt=p.toISOString()}},w=()=>{$.customExpireDate&&($.expiresAt=new Date($.customExpireDate).toISOString())},k=x=>x?new Date(x).toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}):"",d=x=>x?new Date(x)<new Date:!1,l=x=>{if(!x)return null;const p=new Date,H=new Date(x)-p,T=Math.ceil(H/(1e3*60*60*24));return H<0?{text:"已过期",class:"text-red-600"}:T<=7?{text:`${T} 天后过期`,class:"text-orange-600"}:T<=30?{text:`${T} 天后过期`,class:"text-yellow-600"}:{text:`${Math.ceil(T/30)} 个月后过期`,class:"text-green-600"}},N=()=>{C.value=!0,j("save",{keyId:M.apiKey.id,expiresAt:$.expiresAt})};return V({resetSaving:()=>{C.value=!1}}),(x,p)=>(n(),Z(ue,{to:"body"},[I.show?(n(),i("div",$o,[e("div",ho,[e("div",Ao,[e("div",Co,[p[5]||(p[5]=e("div",{class:"w-10 h-10 bg-gradient-to-br from-amber-500 to-orange-600 rounded-xl flex items-center justify-center"},[e("i",{class:"fas fa-clock text-white"})],-1)),e("div",null,[p[4]||(p[4]=e("h3",{class:"text-xl font-bold text-gray-900"}," 修改过期时间 ",-1)),e("p",Ko,' 为 "'+u(I.apiKey.name||"API Key")+'" 设置新的过期时间 ',1)])]),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors",onClick:p[0]||(p[0]=Y=>x.$emit("close"))},p[6]||(p[6]=[e("i",{class:"fas fa-times text-xl"},null,-1)]))]),e("div",ko,[e("div",_o,[e("div",Do,[e("div",null,[p[9]||(p[9]=e("p",{class:"text-xs text-gray-600 font-medium mb-1"}," 当前过期时间 ",-1)),e("p",Io,[I.apiKey.expiresAt?(n(),i(R,{key:0},[h(u(k(I.apiKey.expiresAt))+" ",1),l(I.apiKey.expiresAt)?(n(),i("span",{key:0,class:P(["ml-2 text-xs font-normal",l(I.apiKey.expiresAt).class])}," ("+u(l(I.apiKey.expiresAt).text)+") ",3)):y("",!0)],64)):(n(),i(R,{key:1},[p[7]||(p[7]=e("i",{class:"fas fa-infinity mr-1 text-gray-500"},null,-1)),p[8]||(p[8]=h(" 永不过期 ",-1))],64))])]),e("div",Lo,[e("i",{class:P(["fas fa-hourglass-half text-lg",I.apiKey.expiresAt&&d(I.apiKey.expiresAt)?"text-red-500":"text-gray-400"])},null,2)])])]),e("div",null,[p[11]||(p[11]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"选择新的期限",-1)),e("div",To,[(n(),i(R,null,G(O,Y=>e("button",{key:Y.value,class:P(["px-3 py-2 rounded-lg text-sm font-medium transition-all",$.expireDuration===Y.value?"bg-blue-500 text-white shadow-md":"bg-gray-100 text-gray-700 hover:bg-gray-200"]),onClick:H=>L(Y.value)},u(Y.label),11,Mo)),64)),e("button",{class:P(["px-3 py-2 rounded-lg text-sm font-medium transition-all",$.expireDuration==="custom"?"bg-blue-500 text-white shadow-md":"bg-gray-100 text-gray-700 hover:bg-gray-200"]),onClick:p[1]||(p[1]=Y=>L("custom"))},p[10]||(p[10]=[e("i",{class:"fas fa-calendar-alt mr-1"},null,-1),h(" 自定义 ",-1)]),2)])]),$.expireDuration==="custom"?(n(),i("div",So,[p[12]||(p[12]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"选择日期和时间",-1)),D(e("input",{"onUpdate:modelValue":p[2]||(p[2]=Y=>$.customExpireDate=Y),type:"datetime-local",class:"form-input w-full",min:b.value,onChange:w},null,40,jo),[[z,$.customExpireDate]]),p[13]||(p[13]=e("p",{class:"text-xs text-gray-500 mt-2"}," 选择一个未来的日期和时间作为过期时间 ",-1))])):y("",!0),$.expiresAt!==I.apiKey.expiresAt?(n(),i("div",Ro,[e("div",Eo,[e("div",null,[p[16]||(p[16]=e("p",{class:"text-xs text-blue-700 font-medium mb-1"},[e("i",{class:"fas fa-arrow-right mr-1"}),h(" 新的过期时间 ")],-1)),e("p",Po,[$.expiresAt?(n(),i(R,{key:0},[h(u(k($.expiresAt))+" ",1),l($.expiresAt)?(n(),i("span",{key:0,class:P(["ml-2 text-xs font-normal",l($.expiresAt).class])}," ("+u(l($.expiresAt).text)+") ",3)):y("",!0)],64)):(n(),i(R,{key:1},[p[14]||(p[14]=e("i",{class:"fas fa-infinity mr-1"},null,-1)),p[15]||(p[15]=h(" 永不过期 ",-1))],64))])]),p[17]||(p[17]=e("div",{class:"w-12 h-12 bg-white rounded-lg flex items-center justify-center shadow-sm"},[e("i",{class:"fas fa-check text-lg text-green-500"})],-1))])])):y("",!0),e("div",Uo,[e("button",{class:"flex-1 px-4 py-2.5 bg-gray-100 text-gray-700 rounded-lg font-semibold hover:bg-gray-200 transition-colors",onClick:p[3]||(p[3]=Y=>x.$emit("close"))}," 取消 "),e("button",{class:"flex-1 btn btn-primary py-2.5 px-4 font-semibold",disabled:C.value||$.expiresAt===I.apiKey.expiresAt,onClick:N},[C.value?(n(),i("div",Go)):(n(),i("i",Oo)),h(" "+u(C.value?"保存中...":"保存更改"),1)],8,Vo)])])])])):y("",!0)]))}},Fo=ae(qo,[["__scopeId","data-v-060bf571"]]),Wo={class:"tab-content"},zo={class:"card p-4 sm:p-6"},No={class:"flex flex-col gap-4 mb-4 sm:mb-6"},Yo={class:"flex flex-col sm:flex-row gap-3 sm:items-center sm:justify-between"},Bo={class:"flex flex-wrap gap-2 items-center"},Ho=["value"],Qo={key:0,class:"text-center py-12"},Xo={key:1,class:"text-center py-12"},Jo={key:2,class:"hidden md:block table-container"},Zo={class:"w-full table-fixed"},en={class:"bg-gray-50/80 backdrop-blur-sm"},tn={key:1,class:"fas fa-sort ml-1 text-gray-400"},sn={key:1,class:"fas fa-sort ml-1 text-gray-400"},ln={class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider w-[17%] min-w-[140px]"},on={key:1,class:"fas fa-sort ml-1 text-gray-400"},nn={key:1,class:"fas fa-sort ml-1 text-gray-400"},an={key:1,class:"fas fa-sort ml-1 text-gray-400"},rn={class:"divide-y divide-gray-200/50"},dn={class:"table-row"},un={class:"px-3 py-4"},cn={class:"flex items-center"},mn={class:"min-w-0"},pn=["title"],xn=["title"],gn={class:"text-xs text-gray-500 mt-1 truncate"},fn=["title"],yn={key:1},bn={class:"px-3 py-4"},vn={class:"flex flex-wrap gap-1"},wn={key:0,class:"text-xs text-gray-400"},$n={class:"px-3 py-4 whitespace-nowrap"},hn={class:"px-3 py-4"},An={class:"space-y-1"},Cn={class:"flex justify-between text-sm"},Kn={class:"font-medium text-gray-900"},kn={class:"flex justify-between text-sm"},_n={class:"font-medium text-gray-900"},Dn={class:"flex justify-between text-sm"},In={class:"font-medium text-green-600"},Ln={key:0,class:"flex justify-between text-sm"},Tn={class:"flex justify-between text-sm"},Mn={class:"font-medium text-purple-600"},Sn={class:"flex justify-between text-sm"},jn={key:0,class:"text-xs text-gray-500"},Rn={key:1,class:"flex justify-between text-sm"},En={class:"font-medium text-indigo-600"},Pn={key:2,class:"flex justify-between text-sm"},Un={class:"font-medium text-indigo-600"},Vn={class:"flex justify-between text-xs text-gray-500"},Gn={key:3,class:"flex justify-between text-xs text-orange-500"},On={class:"flex justify-between text-xs text-blue-600"},qn={class:"pt-1 border-t border-gray-100"},Fn={class:"flex justify-between text-xs text-green-600"},Wn={class:"pt-2"},zn=["onClick"],Nn={class:"px-3 py-4 whitespace-nowrap text-sm text-gray-500"},Yn={class:"px-3 py-4 whitespace-nowrap text-sm"},Bn={class:"inline-flex items-center gap-1 group"},Hn={key:0},Qn={key:0,class:"text-red-600"},Xn={key:1,class:"text-orange-600"},Jn={key:2,class:"text-gray-600"},Zn={key:1,class:"text-gray-400"},ei=["onClick"],ti={class:"px-3 py-4 whitespace-nowrap text-sm"},si={class:"flex gap-1"},li=["onClick"],oi=["onClick"],ni=["onClick"],ii=["onClick"],ai={key:0},ri={colspan:"7",class:"px-3 py-4 bg-gray-50"},di={key:0,class:"text-center py-4"},ui={class:"space-y-4"},ci={class:"flex items-center justify-between mb-4"},mi={class:"flex items-center gap-2"},pi={key:0,class:"text-xs text-gray-500 bg-gray-100 px-2 py-1 rounded-full"},xi={class:"flex gap-1 items-center"},gi={class:"flex gap-1 bg-gray-100 rounded p-1"},fi=["onClick"],yi={key:0,class:"text-center py-8"},bi={class:"flex items-center justify-center gap-2 mb-3"},vi=["onClick"],wi={key:1,class:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"},$i={class:"flex justify-between items-start mb-3"},hi={class:"flex-1"},Ai={class:"text-sm font-semibold text-gray-800 block mb-1"},Ci={class:"text-xs text-gray-500 bg-blue-50 px-2 py-1 rounded-full"},Ki={class:"space-y-2 mb-3"},ki={class:"flex justify-between items-center text-sm"},_i={class:"font-semibold text-gray-900"},Di={class:"flex justify-between items-center text-sm"},Ii={class:"font-semibold text-green-600"},Li={class:"pt-2 mt-2 border-t border-gray-100"},Ti={class:"flex justify-between items-center text-xs text-gray-500"},Mi={class:"font-medium"},Si={class:"flex justify-between items-center text-xs text-gray-500"},ji={class:"font-medium"},Ri={key:0,class:"flex justify-between items-center text-xs text-purple-600"},Ei={class:"font-medium"},Pi={key:1,class:"flex justify-between items-center text-xs text-purple-600"},Ui={class:"font-medium"},Vi={class:"w-full bg-gray-200 rounded-full h-2 mt-3"},Gi={class:"text-right mt-1"},Oi={class:"text-xs font-medium text-indigo-600"},qi={key:2,class:"mt-4 p-3 bg-gradient-to-r from-indigo-50 to-purple-50 rounded-lg border border-indigo-100"},Fi={class:"flex items-center justify-between text-sm"},Wi={class:"flex gap-4 text-xs"},zi={class:"text-gray-600"},Ni={class:"font-semibold text-gray-800"},Yi={class:"text-gray-600"},Bi={class:"font-semibold text-gray-800"},Hi={key:3,class:"md:hidden space-y-3"},Qi={class:"flex items-start justify-between mb-3"},Xi={class:"flex items-center gap-3"},Ji={class:"text-sm font-semibold text-gray-900"},Zi={class:"text-xs text-gray-500 mt-0.5"},ea={class:"mb-3 text-xs text-gray-600"},ta={key:0},sa={key:1},la={class:"grid grid-cols-2 gap-3 mb-3"},oa={class:"text-sm font-semibold text-gray-900"},na={class:"text-xs text-gray-500 mt-0.5"},ia={class:"text-sm font-semibold text-green-600"},aa={class:"text-xs text-gray-500 mb-3"},ra={class:"flex justify-between mb-1"},da={class:"flex justify-between"},ua={key:0,class:"flex flex-wrap gap-1 mb-3"},ca={class:"flex gap-2 mt-3 pt-3 border-t border-gray-100"},ma=["onClick"],pa=["onClick"],xa=["onClick"],ga=["onClick"],fa={key:1,class:"mt-3 pt-3 border-t border-gray-100"},ya={class:"space-y-2 text-xs"},ba={class:"flex justify-between"},va={class:"font-medium text-purple-600"},wa={class:"flex justify-between"},$a={key:0,class:"text-xs text-gray-500"},ha={key:0,class:"flex justify-between"},Aa={key:1,class:"flex justify-between"},Ca={class:"font-medium text-indigo-600"},Ka={key:2,class:"flex justify-between"},ka={class:"font-medium text-indigo-600"},_a={class:"pt-2 mt-2 border-t border-gray-100"},Da={class:"flex justify-between"},Ia={class:"font-medium"},La={class:"flex justify-between"},Ta={class:"font-medium"},Ma={key:0,class:"flex justify-between"},Sa={class:"font-medium text-purple-600"},ja={key:1,class:"flex justify-between"},Ra={class:"font-medium text-purple-600"},Ea={class:"pt-2 mt-2 border-t border-gray-100"},Pa={class:"flex justify-between"},Ua={class:"font-medium text-green-600"},Va={class:"flex justify-between"},Ga={class:"font-medium text-green-600"},Oa={key:4,class:"mt-4 sm:mt-6 flex flex-col sm:flex-row justify-between items-center gap-4"},qa={class:"flex flex-col sm:flex-row items-center gap-3 w-full sm:w-auto"},Fa={class:"text-xs sm:text-sm text-gray-600"},Wa={class:"flex items-center gap-2"},za=["value"],Na={class:"flex items-center gap-2"},Ya=["disabled"],Ba={class:"flex items-center gap-1"},Ha={key:1,class:"hidden sm:inline px-2 text-gray-500"},Qa=["onClick"],Xa={key:2,class:"hidden sm:inline px-2 text-gray-500"},Ja=["disabled"],Za={__name:"ApiKeysView",setup(I){const V=Ae(),f=K([]),M=K(!1),j=K("today"),C=K(""),$=K("asc"),O=K({}),b=K({}),q=K({}),L=K([new Date(2e3,1,1,0,0,0),new Date(2e3,2,1,23,59,59)]),w=K({claude:[],gemini:[],claudeGroups:[],geminiGroups:[]}),k=K(null),d=K(null),l=K(""),N=K([]),A=K([]),x=K(1),p=K(10),Y=[10,20,50,100],H=K(!1),T=K(!1),a=K(!1),m=K(!1),B=K(!1),te=K(null),_=K(null),o=K(null),r=K([]),F=ee(()=>{let c=f.value;return l.value&&(c=f.value.filter(v=>v.tags&&v.tags.includes(l.value))),C.value?[...c].sort((v,t)=>{let g=v[C.value],E=t[C.value];return C.value==="status"?(g=v.isActive?1:0,E=t.isActive?1:0):C.value==="cost"?(g=parseFloat(me(v.usage).replace("$","")),E=parseFloat(me(t.usage).replace("$",""))):(C.value==="createdAt"||C.value==="expiresAt")&&(g=g?new Date(g).getTime():0,E=E?new Date(E).getTime():0),g<E?$.value==="asc"?-1:1:g>E?$.value==="asc"?1:-1:0}):c}),Q=ee(()=>{const c=F.value.length;return Math.ceil(c/p.value)||0}),se=ee(()=>{const c=[],s=x.value,v=Q.value;if(v<=7)for(let t=1;t<=v;t++)c.push(t);else{let t=Math.max(1,s-2),g=Math.min(v,s+2);s<=3?g=5:s>=v-2&&(t=v-4);for(let E=t;E<=g;E++)c.push(E)}return c}),re=ee(()=>{const c=(x.value-1)*p.value,s=c+p.value;return F.value.slice(c,s)}),X=async()=>{try{const[c,s,v,t]=await Promise.all([U.get("/admin/claude-accounts"),U.get("/admin/claude-console-accounts"),U.get("/admin/gemini-accounts"),U.get("/admin/account-groups")]);if(c.success&&(w.value.claude=c.data||[]),s.success){const g=(s.data||[]).map(E=>({...E,platform:"claude-console"}));w.value.claude=[...w.value.claude,...g]}if(v.success&&(w.value.gemini=v.data||[]),t.success){const g=t.data||[];w.value.claudeGroups=g.filter(E=>E.platform==="claude"),w.value.geminiGroups=g.filter(E=>E.platform==="gemini")}}catch(c){console.error("加载账户列表失败:",c)}},J=async()=>{M.value=!0;try{const c=await U.get(`/admin/api-keys?timeRange=${j.value}`);if(c.success){f.value=c.data||[];const s=new Set;f.value.forEach(v=>{v.tags&&Array.isArray(v.tags)&&v.tags.forEach(t=>s.add(t))}),N.value=Array.from(s).sort()}}catch{S("加载 API Keys 失败","error")}finally{M.value=!1}},ce=c=>{C.value===c?$.value=$.value==="asc"?"desc":"asc":(C.value=c,$.value="asc")},W=c=>!c&&c!==0?"0":c.toLocaleString("zh-CN"),me=c=>!c||!c.total?"$0.0000":`$${(c.total.cost||0).toFixed(4)}`,ve=c=>{if(!c)return"未知账户";const s=w.value.claude.find(t=>t.id===c);if(s)return s.name;const v=w.value.gemini.find(t=>t.id===c);return v?v.name:`账户-${c.substring(0,8)}`},pe=c=>c?new Date(c)<new Date:!1,xe=c=>!c||pe(c)?!1:(new Date(c)-new Date)/(1e3*60*60*24)<=7,Ce=c=>c?new Date(c).toLocaleDateString("zh-CN"):"",Pe=async c=>{O.value[c]?O.value[c]=!1:(O.value[c]=!0,q.value[c]||ke(c),await ge(c,!0))},ge=async(c,s=!1)=>{if(!s&&b.value[c]&&b.value[c].length>0)return;const v=oe(c);try{let t=`/admin/api-keys/${c}/model-stats`;const g=new URLSearchParams;if(v.customStart&&v.customEnd)g.append("startDate",v.customStart),g.append("endDate",v.customEnd),g.append("period","custom");else{const fe=v.preset==="today"?"daily":"monthly";g.append("period",fe)}t+="?"+g.toString();const E=await U.get(t);E.success&&(b.value[c]=E.data||[])}catch{S("加载模型统计失败","error"),b.value[c]=[]}},Ke=(c,s)=>{const v=s.reduce((t,g)=>t+(g.allTokens||0),0);return v===0?0:Math.round(c/v*100)},Ue=c=>c.formatted&&c.formatted.total?c.formatted.total:c.cost!==void 0?`$${c.cost.toFixed(6)}`:"$0.000000",ke=c=>{const s=new Date,v=new Date(s);v.setDate(s.getDate()-6),q.value[c]={type:"preset",preset:"7days",customStart:v.toISOString().split("T")[0],customEnd:s.toISOString().split("T")[0],customRange:null,presetOptions:[{value:"today",label:"今日",days:1},{value:"7days",label:"7天",days:7},{value:"30days",label:"30天",days:30}]}},oe=c=>(q.value[c]||ke(c),q.value[c]),_e=(c,s)=>{const v=oe(s);v.type="preset",v.preset=c;const t=v.presetOptions.find(g=>g.value===c);if(t){const g=new Date,E=new Date(g);E.setDate(g.getDate()-(t.days-1)),v.customStart=E.toISOString().split("T")[0],v.customEnd=g.toISOString().split("T")[0];const fe=we=>we.getFullYear()+"-"+String(we.getMonth()+1).padStart(2,"0")+"-"+String(we.getDate()).padStart(2,"0")+" 00:00:00";v.customRange=[fe(E),fe(g)]}ge(s,!0)},Ve=(c,s)=>{const v=oe(c);s&&s.length===2?(v.type="custom",v.preset="",v.customRange=s,v.customStart=s[0].split(" ")[0],v.customEnd=s[1].split(" ")[0],ge(c,!0)):s===null&&_e("7days",c)},Ge=c=>c>new Date,Oe=c=>{const s=oe(c);s.type="preset",s.preset="7days";const v=new Date,t=new Date(v);t.setDate(v.getDate()-6),s.customStart=t.toISOString().split("T")[0],s.customEnd=v.toISOString().split("T")[0],s.customRange=null,ge(c,!0),S("已重置筛选条件并刷新数据","info")},qe=async()=>{await X(),H.value=!0},De=async c=>{await X(),te.value=c,T.value=!0},Ie=c=>{_.value=c,a.value=!0},Fe=c=>{H.value=!1,o.value=c,m.value=!0,J()},We=c=>{H.value=!1,r.value=c,B.value=!0,J()},ze=()=>{T.value=!1,S("API Key 更新成功","success"),J()},Ne=()=>{a.value=!1,S("API Key 续期成功","success"),J()},Le=async c=>{let s=!1;if(window.showConfirm?s=await window.showConfirm("删除 API Key","确定要删除这个 API Key 吗?此操作不可恢复。","确定删除","取消"):s=confirm("确定要删除这个 API Key 吗?此操作不可恢复。"),!!s)try{const v=await U.delete(`/admin/api-keys/${c}`);v.success?(S("API Key 已删除","success"),J()):S(v.message||"删除失败","error")}catch{S("删除失败","error")}},Ye=c=>{const v=`${window.location.origin}/admin/api-stats?apiId=${c.id}`,t=document.createElement("textarea");t.value=v,t.style.position="fixed",t.style.opacity="0",t.style.left="-9999px",document.body.appendChild(t),t.select(),t.setSelectionRange(0,99999);try{document.execCommand("copy")?S("已复制统计页面链接","success"):(S("复制失败,请手动复制","error"),console.log("统计页面链接:",v))}catch(g){S("复制失败,请手动复制","error"),console.error("复制错误:",g),console.log("统计页面链接:",v)}finally{document.body.removeChild(t)}},Be=c=>{k.value=c},Te=()=>{k.value=null},He=async({keyId:c,expiresAt:s})=>{try{const v=await U.put(`/admin/api-keys/${c}`,{expiresAt:s||null});if(v.success){S("过期时间已更新","success");const t=f.value.find(g=>g.id===c);t&&(t.expiresAt=s||null),Te()}else S(v.message||"更新失败","error"),d.value&&d.value.resetSaving()}catch{S("更新失败","error"),d.value&&d.value.resetSaving()}},Qe=c=>{const s=A.value.indexOf(c);s>-1?A.value.splice(s,1):A.value.push(c)},Me=c=>c?new Date(c).toLocaleDateString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}).replace(/\//g,"-"):"";return $e([l,j],()=>{x.value=1}),he(async()=>{await Promise.all([V.loadSupportedClients(),X(),J()])}),(c,s)=>{const v=Xe;return n(),i("div",Wo,[e("div",zo,[e("div",No,[s[23]||(s[23]=e("div",null,[e("h3",{class:"text-lg sm:text-xl font-bold text-gray-900 mb-1 sm:mb-2"}," API Keys 管理 "),e("p",{class:"text-sm sm:text-base text-gray-600"}," 管理和监控您的 API 密钥 ")],-1)),e("div",Yo,[e("div",Bo,[D(e("select",{"onUpdate:modelValue":s[0]||(s[0]=t=>j.value=t),class:"px-3 py-2 text-sm text-gray-700 bg-white border border-gray-200 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent hover:border-gray-300 transition-colors",onChange:s[1]||(s[1]=t=>J())},s[20]||(s[20]=[e("option",{value:"today"}," 今日 ",-1),e("option",{value:"7days"}," 最近7天 ",-1),e("option",{value:"monthly"}," 本月 ",-1),e("option",{value:"all"}," 全部时间 ",-1)]),544),[[le,j.value]]),D(e("select",{"onUpdate:modelValue":s[2]||(s[2]=t=>l.value=t),class:"px-3 py-2 text-sm text-gray-700 bg-white border border-gray-200 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent hover:border-gray-300 transition-colors",onChange:s[3]||(s[3]=t=>x.value=1)},[s[21]||(s[21]=e("option",{value:""}," 所有标签 ",-1)),(n(!0),i(R,null,G(N.value,t=>(n(),i("option",{key:t,value:t},u(t),9,Ho))),128))],544),[[le,l.value]])]),e("button",{class:"btn btn-primary px-4 py-2 text-sm flex items-center gap-2 w-full sm:w-auto justify-center",onClick:ie(qe,["stop"])},s[22]||(s[22]=[e("i",{class:"fas fa-plus"},null,-1),h("创建新 Key ",-1)]))])]),M.value?(n(),i("div",Qo,s[24]||(s[24]=[e("div",{class:"loading-spinner mx-auto mb-4"},null,-1),e("p",{class:"text-gray-500"}," 正在加载 API Keys... ",-1)]))):f.value.length===0?(n(),i("div",Xo,s[25]||(s[25]=[e("div",{class:"w-16 h-16 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center"},[e("i",{class:"fas fa-key text-gray-400 text-xl"})],-1),e("p",{class:"text-gray-500 text-lg"}," 暂无 API Keys ",-1),e("p",{class:"text-gray-400 text-sm mt-2"}," 点击上方按钮创建您的第一个 API Key ",-1)]))):(n(),i("div",Jo,[e("table",Zo,[e("thead",en,[e("tr",null,[e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider cursor-pointer hover:bg-gray-100 w-[25%] min-w-[200px]",onClick:s[4]||(s[4]=t=>ce("name"))},[s[26]||(s[26]=h(" 名称 ",-1)),C.value==="name"?(n(),i("i",{key:0,class:P(["fas",$.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(n(),i("i",tn))]),s[33]||(s[33]=e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider w-[10%] min-w-[80px]"}," 标签 ",-1)),e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider cursor-pointer hover:bg-gray-100 w-[8%] min-w-[70px]",onClick:s[5]||(s[5]=t=>ce("status"))},[s[27]||(s[27]=h(" 状态 ",-1)),C.value==="status"?(n(),i("i",{key:0,class:P(["fas",$.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(n(),i("i",sn))]),e("th",ln,[s[30]||(s[30]=h(" 使用统计 ",-1)),e("span",{class:"cursor-pointer hover:bg-gray-100 px-2 py-1 rounded",onClick:s[6]||(s[6]=t=>ce("cost"))},[s[28]||(s[28]=h(" (费用 ",-1)),C.value==="cost"?(n(),i("i",{key:0,class:P(["fas",$.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(n(),i("i",on)),s[29]||(s[29]=h(") ",-1))])]),e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider cursor-pointer hover:bg-gray-100 w-[10%] min-w-[90px]",onClick:s[7]||(s[7]=t=>ce("createdAt"))},[s[31]||(s[31]=h(" 创建时间 ",-1)),C.value==="createdAt"?(n(),i("i",{key:0,class:P(["fas",$.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(n(),i("i",nn))]),e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider cursor-pointer hover:bg-gray-100 w-[10%] min-w-[90px]",onClick:s[8]||(s[8]=t=>ce("expiresAt"))},[s[32]||(s[32]=h(" 过期时间 ",-1)),C.value==="expiresAt"?(n(),i("i",{key:0,class:P(["fas",$.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(n(),i("i",an))]),s[34]||(s[34]=e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider w-[20%] min-w-[180px]"}," 操作 ",-1))])]),e("tbody",rn,[(n(!0),i(R,null,G(re.value,t=>(n(),i(R,{key:t.id},[e("tr",dn,[e("td",un,[e("div",cn,[s[37]||(s[37]=e("div",{class:"w-8 h-8 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg flex items-center justify-center mr-2 flex-shrink-0"},[e("i",{class:"fas fa-key text-white text-xs"})],-1)),e("div",mn,[e("div",{class:"text-sm font-semibold text-gray-900 truncate",title:t.name},u(t.name),9,pn),e("div",{class:"text-xs text-gray-500 truncate",title:t.id},u(t.id),9,xn),e("div",gn,[t.claudeAccountId?(n(),i("span",{key:0,title:`绑定: ${ve(t.claudeAccountId)}`},[s[35]||(s[35]=e("i",{class:"fas fa-link mr-1"},null,-1)),h(" "+u(ve(t.claudeAccountId)),1)],8,fn)):(n(),i("span",yn,s[36]||(s[36]=[e("i",{class:"fas fa-share-alt mr-1"},null,-1),h(" 共享池 ",-1)])))])])])]),e("td",bn,[e("div",vn,[(n(!0),i(R,null,G(t.tags||[],g=>(n(),i("span",{key:g,class:"inline-flex items-center px-2 py-0.5 bg-blue-100 text-blue-800 text-xs rounded-full"},u(g),1))),128)),!t.tags||t.tags.length===0?(n(),i("span",wn,"无标签")):y("",!0)])]),e("td",$n,[e("span",{class:P(["inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold",t.isActive?"bg-green-100 text-green-800":"bg-red-100 text-red-800"])},[e("div",{class:P(["w-2 h-2 rounded-full mr-2",t.isActive?"bg-green-500":"bg-red-500"])},null,2),h(" "+u(t.isActive?"活跃":"禁用"),1)],2)]),e("td",hn,[e("div",An,[e("div",Cn,[s[38]||(s[38]=e("span",{class:"text-gray-600"},"请求数:",-1)),e("span",Kn,u(W(t.usage&&t.usage.total&&t.usage.total.requests||0)),1)]),e("div",kn,[s[39]||(s[39]=e("span",{class:"text-gray-600"},"Token:",-1)),e("span",_n,u(W(t.usage&&t.usage.total&&t.usage.total.tokens||0)),1)]),e("div",Dn,[s[40]||(s[40]=e("span",{class:"text-gray-600"},"费用:",-1)),e("span",In,u(me(t.usage)),1)]),t.dailyCostLimit>0?(n(),i("div",Ln,[s[41]||(s[41]=e("span",{class:"text-gray-600"},"今日费用:",-1)),e("span",{class:P(["font-medium",(t.dailyCost||0)>=t.dailyCostLimit?"text-red-600":"text-blue-600"])}," $"+u((t.dailyCost||0).toFixed(2))+" / $"+u(t.dailyCostLimit.toFixed(2)),3)])):y("",!0),e("div",Tn,[s[42]||(s[42]=e("span",{class:"text-gray-600"},"并发限制:",-1)),e("span",Mn,u(t.concurrencyLimit>0?t.concurrencyLimit:"无限制"),1)]),e("div",Sn,[s[43]||(s[43]=e("span",{class:"text-gray-600"},"当前并发:",-1)),e("span",{class:P(["font-medium",t.currentConcurrency>0?"text-orange-600":"text-gray-600"])},[h(u(t.currentConcurrency||0)+" ",1),t.concurrencyLimit>0?(n(),i("span",jn,"/ "+u(t.concurrencyLimit),1)):y("",!0)],2)]),t.rateLimitWindow>0?(n(),i("div",Rn,[s[44]||(s[44]=e("span",{class:"text-gray-600"},"时间窗口:",-1)),e("span",En,u(t.rateLimitWindow)+" 分钟",1)])):y("",!0),t.rateLimitRequests>0?(n(),i("div",Pn,[s[45]||(s[45]=e("span",{class:"text-gray-600"},"请求限制:",-1)),e("span",Un,u(t.rateLimitRequests)+" 次/窗口",1)])):y("",!0),e("div",Vn,[e("span",null,"输入: "+u(W(t.usage&&t.usage.total&&t.usage.total.inputTokens||0)),1),e("span",null,"输出: "+u(W(t.usage&&t.usage.total&&t.usage.total.outputTokens||0)),1)]),(t.usage&&t.usage.total&&t.usage.total.cacheCreateTokens||0)>0||(t.usage&&t.usage.total&&t.usage.total.cacheReadTokens||0)>0?(n(),i("div",Gn,[e("span",null,"缓存创建: "+u(W(t.usage&&t.usage.total&&t.usage.total.cacheCreateTokens||0)),1),e("span",null,"缓存读取: "+u(W(t.usage&&t.usage.total&&t.usage.total.cacheReadTokens||0)),1)])):y("",!0),e("div",On,[e("span",null,"RPM: "+u(t.usage&&t.usage.averages&&t.usage.averages.rpm||0),1),e("span",null,"TPM: "+u(t.usage&&t.usage.averages&&t.usage.averages.tpm||0),1)]),e("div",qn,[e("div",Fn,[e("span",null,"今日: "+u(W(t.usage&&t.usage.daily&&t.usage.daily.requests||0))+"次",1),e("span",null,u(W(t.usage&&t.usage.daily&&t.usage.daily.tokens||0))+"T",1)])]),e("div",Wn,[t&&t.id?(n(),i("button",{key:0,class:"text-xs text-indigo-600 hover:text-indigo-800 font-medium",onClick:g=>Pe(t.id)},[e("i",{class:P(["fas",O.value[t.id]?"fa-chevron-up":"fa-chevron-down","mr-1"])},null,2),s[46]||(s[46]=h(" 模型使用分布 ",-1))],8,zn)):y("",!0)])])]),e("td",Nn,u(new Date(t.createdAt).toLocaleDateString()),1),e("td",Yn,[e("div",Bn,[t.expiresAt?(n(),i("span",Hn,[pe(t.expiresAt)?(n(),i("span",Qn,s[47]||(s[47]=[e("i",{class:"fas fa-exclamation-circle mr-1"},null,-1),h(" 已过期 ",-1)]))):xe(t.expiresAt)?(n(),i("span",Xn,[s[48]||(s[48]=e("i",{class:"fas fa-clock mr-1"},null,-1)),h(" "+u(Ce(t.expiresAt)),1)])):(n(),i("span",Jn,u(Ce(t.expiresAt)),1))])):(n(),i("span",Zn,s[49]||(s[49]=[e("i",{class:"fas fa-infinity mr-1"},null,-1),h(" 永不过期 ",-1)]))),e("button",{class:"opacity-0 group-hover:opacity-100 p-0.5 text-gray-400 hover:text-blue-600 rounded transition-all duration-200",title:"快速修改过期时间",onClick:ie(g=>Be(t),["stop"])},s[50]||(s[50]=[e("i",{class:"fas fa-pencil-alt text-xs"},null,-1)]),8,ei)])]),e("td",ti,[e("div",si,[e("button",{class:"text-purple-600 hover:text-purple-900 font-medium hover:bg-purple-50 px-2 py-1 rounded transition-colors text-xs",title:"复制统计页面链接",onClick:g=>Ye(t)},s[51]||(s[51]=[e("i",{class:"fas fa-chart-bar"},null,-1),e("span",{class:"hidden xl:inline ml-1"},"统计",-1)]),8,li),e("button",{class:"text-blue-600 hover:text-blue-900 font-medium hover:bg-blue-50 px-2 py-1 rounded transition-colors text-xs",title:"编辑",onClick:g=>De(t)},s[52]||(s[52]=[e("i",{class:"fas fa-edit"},null,-1),e("span",{class:"hidden xl:inline ml-1"},"编辑",-1)]),8,oi),t.expiresAt&&(pe(t.expiresAt)||xe(t.expiresAt))?(n(),i("button",{key:0,class:"text-green-600 hover:text-green-900 font-medium hover:bg-green-50 px-2 py-1 rounded transition-colors text-xs",title:"续期",onClick:g=>Ie(t)},s[53]||(s[53]=[e("i",{class:"fas fa-clock"},null,-1),e("span",{class:"hidden xl:inline ml-1"},"续期",-1)]),8,ni)):y("",!0),e("button",{class:"text-red-600 hover:text-red-900 font-medium hover:bg-red-50 px-2 py-1 rounded transition-colors text-xs",title:"删除",onClick:g=>Le(t.id)},s[54]||(s[54]=[e("i",{class:"fas fa-trash"},null,-1),e("span",{class:"hidden xl:inline ml-1"},"删除",-1)]),8,ii)])])]),t&&t.id&&O.value[t.id]?(n(),i("tr",ai,[e("td",ri,[b.value[t.id]?y("",!0):(n(),i("div",di,s[55]||(s[55]=[e("div",{class:"loading-spinner mx-auto"},null,-1),e("p",{class:"text-sm text-gray-500 mt-2"}," 加载模型统计... ",-1)]))),e("div",ui,[e("div",ci,[s[56]||(s[56]=e("h5",{class:"text-sm font-semibold text-gray-700 flex items-center"},[e("i",{class:"fas fa-chart-pie text-indigo-500 mr-2"}),h(" 模型使用分布 ")],-1)),e("div",mi,[b.value[t.id]&&b.value[t.id].length>0?(n(),i("span",pi,u(b.value[t.id].length)+" 个模型 ",1)):y("",!0),e("div",xi,[e("div",gi,[(n(!0),i(R,null,G(oe(t.id).presetOptions,g=>(n(),i("button",{key:g.value,class:P(["px-2 py-1 rounded text-xs font-medium transition-colors",oe(t.id).preset===g.value&&oe(t.id).type==="preset"?"bg-white text-blue-600 shadow-sm":"text-gray-600 hover:text-gray-900"]),onClick:E=>_e(g.value,t.id)},u(g.label),11,fi))),128))]),Se(v,{"model-value":oe(t.id).customRange,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":Ge,"default-time":L.value,size:"small",style:{width:"280px"},"onUpdate:modelValue":g=>Ve(t.id,g),class:"api-key-date-picker",clearable:!0,"unlink-panels":!1},null,8,["model-value","default-time","onUpdate:modelValue"])])])]),b.value[t.id]&&b.value[t.id].length===0?(n(),i("div",yi,[e("div",bi,[s[58]||(s[58]=e("i",{class:"fas fa-chart-line text-gray-400 text-lg"},null,-1)),s[59]||(s[59]=e("p",{class:"text-sm text-gray-500"}," 暂无模型使用数据 ",-1)),e("button",{class:"text-blue-500 hover:text-blue-700 text-sm ml-2 flex items-center gap-1 transition-colors",title:"重置筛选条件并刷新",onClick:g=>Oe(t.id)},s[57]||(s[57]=[e("i",{class:"fas fa-sync-alt text-xs"},null,-1),e("span",{class:"text-xs"},"刷新",-1)]),8,vi)]),s[60]||(s[60]=e("p",{class:"text-xs text-gray-400"}," 尝试调整时间范围或点击刷新重新加载数据 ",-1))])):b.value[t.id]&&b.value[t.id].length>0?(n(),i("div",wi,[(n(!0),i(R,null,G(b.value[t.id],g=>(n(),i("div",{key:g.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"},[e("div",$i,[e("div",hi,[e("span",Ai,u(g.model),1),e("span",Ci,u(g.requests)+" 次请求",1)])]),e("div",Ki,[e("div",ki,[s[61]||(s[61]=e("span",{class:"text-gray-600 flex items-center"},[e("i",{class:"fas fa-coins text-yellow-500 mr-1 text-xs"}),h(" 总Token: ")],-1)),e("span",_i,u(W(g.allTokens)),1)]),e("div",Di,[s[62]||(s[62]=e("span",{class:"text-gray-600 flex items-center"},[e("i",{class:"fas fa-dollar-sign text-green-500 mr-1 text-xs"}),h(" 费用: ")],-1)),e("span",Ii,u(Ue(g)),1)]),e("div",Li,[e("div",Ti,[s[63]||(s[63]=e("span",{class:"flex items-center"},[e("i",{class:"fas fa-arrow-down text-green-500 mr-1"}),h(" 输入: ")],-1)),e("span",Mi,u(W(g.inputTokens)),1)]),e("div",Si,[s[64]||(s[64]=e("span",{class:"flex items-center"},[e("i",{class:"fas fa-arrow-up text-blue-500 mr-1"}),h(" 输出: ")],-1)),e("span",ji,u(W(g.outputTokens)),1)]),g.cacheCreateTokens>0?(n(),i("div",Ri,[s[65]||(s[65]=e("span",{class:"flex items-center"},[e("i",{class:"fas fa-save mr-1"}),h(" 缓存创建: ")],-1)),e("span",Ei,u(W(g.cacheCreateTokens)),1)])):y("",!0),g.cacheReadTokens>0?(n(),i("div",Pi,[s[66]||(s[66]=e("span",{class:"flex items-center"},[e("i",{class:"fas fa-download mr-1"}),h(" 缓存读取: ")],-1)),e("span",Ui,u(W(g.cacheReadTokens)),1)])):y("",!0)])]),e("div",Vi,[e("div",{class:"bg-gradient-to-r from-indigo-500 to-purple-600 h-2 rounded-full transition-all duration-500",style:Je({width:Ke(g.allTokens,b.value[t.id])+"%"})},null,4)]),e("div",Gi,[e("span",Oi,u(Ke(g.allTokens,b.value[t.id]))+"% ",1)])]))),128))])):y("",!0),b.value[t.id]&&b.value[t.id].length>0?(n(),i("div",qi,[e("div",Fi,[s[69]||(s[69]=e("span",{class:"font-semibold text-gray-700 flex items-center"},[e("i",{class:"fas fa-calculator text-indigo-500 mr-2"}),h(" 总计统计 ")],-1)),e("div",Wi,[e("span",zi,[s[67]||(s[67]=h(" 总请求: ",-1)),e("span",Ni,u(b.value[t.id].reduce((g,E)=>g+E.requests,0)),1)]),e("span",Yi,[s[68]||(s[68]=h(" 总Token: ",-1)),e("span",Bi,u(W(b.value[t.id].reduce((g,E)=>g+E.allTokens,0))),1)])])])])):y("",!0)])])])):y("",!0)],64))),128))])])])),!M.value&&F.value.length>0?(n(),i("div",Hi,[(n(!0),i(R,null,G(re.value,t=>(n(),i("div",{key:t.id,class:"card p-4 hover:shadow-lg transition-shadow"},[e("div",Qi,[e("div",Xi,[s[70]||(s[70]=e("div",{class:"w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg flex items-center justify-center flex-shrink-0"},[e("i",{class:"fas fa-key text-white text-sm"})],-1)),e("div",null,[e("h4",Ji,u(t.name),1),e("p",Zi,u(t.id),1)])]),e("span",{class:P(["inline-flex items-center px-2 py-1 rounded-full text-xs font-semibold",t.isActive?"bg-green-100 text-green-800":"bg-red-100 text-red-800"])},[e("div",{class:P(["w-1.5 h-1.5 rounded-full mr-1.5",t.isActive?"bg-green-500":"bg-red-500"])},null,2),h(" "+u(t.isActive?"活跃":"已停用"),1)],2)]),e("div",ea,[t.claudeAccountId||t.claudeConsoleAccountId?(n(),i("span",ta,[s[71]||(s[71]=e("i",{class:"fas fa-link mr-1"},null,-1)),h(" 绑定: "+u(ve(t.claudeAccountId,t.claudeConsoleAccountId)),1)])):(n(),i("span",sa,s[72]||(s[72]=[e("i",{class:"fas fa-share-alt mr-1"},null,-1),h(" 使用共享池 ",-1)])))]),e("div",la,[e("div",null,[s[73]||(s[73]=e("p",{class:"text-xs text-gray-500"}," 使用量 ",-1)),e("p",oa,u(W(t.usage&&t.usage.total&&t.usage.total.requests||0))+" 次 ",1),e("p",na,u(W(t.usage&&t.usage.total&&t.usage.total.tokens||0))+" tokens ",1)]),e("div",null,[s[74]||(s[74]=e("p",{class:"text-xs text-gray-500"}," 费用 ",-1)),e("p",ia,u(me(t.usage)),1)])]),e("div",aa,[e("div",ra,[s[75]||(s[75]=e("span",null,"创建时间",-1)),e("span",null,u(Me(t.createdAt)),1)]),e("div",da,[s[76]||(s[76]=e("span",null,"过期时间",-1)),e("span",{class:P(xe(t.expiresAt)?"text-orange-600 font-semibold":"")},u(t.expiresAt?Me(t.expiresAt):"永不过期"),3)])]),t.tags&&t.tags.length>0?(n(),i("div",ua,[(n(!0),i(R,null,G(t.tags,g=>(n(),i("span",{key:g,class:"inline-flex items-center px-2 py-0.5 bg-blue-100 text-blue-800 text-xs rounded-full"},u(g),1))),128))])):y("",!0),e("div",ca,[e("button",{class:"flex-1 px-3 py-2 text-xs text-blue-600 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors flex items-center justify-center gap-1",onClick:g=>Qe(t.id)},[e("i",{class:P(["fas",A.value.includes(t.id)?"fa-chevron-up":"fa-chevron-down"])},null,2),h(" "+u(A.value.includes(t.id)?"收起":"详情"),1)],8,ma),e("button",{class:"flex-1 px-3 py-2 text-xs text-gray-600 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors",onClick:g=>De(t)},s[77]||(s[77]=[e("i",{class:"fas fa-edit mr-1"},null,-1),h(" 编辑 ",-1)]),8,pa),t.expiresAt&&(pe(t.expiresAt)||xe(t.expiresAt))?(n(),i("button",{key:0,class:"flex-1 px-3 py-2 text-xs text-orange-600 bg-orange-50 rounded-lg hover:bg-orange-100 transition-colors",onClick:g=>Ie(t)},s[78]||(s[78]=[e("i",{class:"fas fa-clock mr-1"},null,-1),h(" 续期 ",-1)]),8,xa)):y("",!0),e("button",{class:"px-3 py-2 text-xs text-red-600 bg-red-50 rounded-lg hover:bg-red-100 transition-colors",onClick:g=>Le(t.id)},s[79]||(s[79]=[e("i",{class:"fas fa-trash"},null,-1)]),8,ga)]),A.value.includes(t.id)?(n(),i("div",fa,[s[91]||(s[91]=e("h5",{class:"text-xs font-semibold text-gray-700 mb-2"}," 详细信息 ",-1)),e("div",ya,[e("div",ba,[s[80]||(s[80]=e("span",{class:"text-gray-600"},"并发限制:",-1)),e("span",va,u(t.concurrencyLimit>0?t.concurrencyLimit:"无限制"),1)]),e("div",wa,[s[81]||(s[81]=e("span",{class:"text-gray-600"},"当前并发:",-1)),e("span",{class:P(["font-medium",t.currentConcurrency>0?"text-orange-600":"text-gray-600"])},[h(u(t.currentConcurrency||0)+" ",1),t.concurrencyLimit>0?(n(),i("span",$a,"/ "+u(t.concurrencyLimit),1)):y("",!0)],2)]),t.dailyCostLimit>0?(n(),i("div",ha,[s[82]||(s[82]=e("span",{class:"text-gray-600"},"今日费用:",-1)),e("span",{class:P(["font-medium",(t.dailyCost||0)>=t.dailyCostLimit?"text-red-600":"text-blue-600"])}," $"+u((t.dailyCost||0).toFixed(2))+" / $"+u(t.dailyCostLimit.toFixed(2)),3)])):y("",!0),t.rateLimitWindow>0?(n(),i("div",Aa,[s[83]||(s[83]=e("span",{class:"text-gray-600"},"时间窗口:",-1)),e("span",Ca,u(t.rateLimitWindow)+" 分钟",1)])):y("",!0),t.rateLimitRequests>0?(n(),i("div",Ka,[s[84]||(s[84]=e("span",{class:"text-gray-600"},"请求限制:",-1)),e("span",ka,u(t.rateLimitRequests)+" 次/窗口",1)])):y("",!0),e("div",_a,[e("div",Da,[s[85]||(s[85]=e("span",{class:"text-gray-600"},"输入 Token:",-1)),e("span",Ia,u(W(t.usage&&t.usage.total&&t.usage.total.inputTokens||0)),1)]),e("div",La,[s[86]||(s[86]=e("span",{class:"text-gray-600"},"输出 Token:",-1)),e("span",Ta,u(W(t.usage&&t.usage.total&&t.usage.total.outputTokens||0)),1)]),(t.usage&&t.usage.total&&t.usage.total.cacheCreateTokens||0)>0?(n(),i("div",Ma,[s[87]||(s[87]=e("span",{class:"text-gray-600"},"缓存创建:",-1)),e("span",Sa,u(W(t.usage&&t.usage.total&&t.usage.total.cacheCreateTokens||0)),1)])):y("",!0),(t.usage&&t.usage.total&&t.usage.total.cacheReadTokens||0)>0?(n(),i("div",ja,[s[88]||(s[88]=e("span",{class:"text-gray-600"},"缓存读取:",-1)),e("span",Ra,u(W(t.usage&&t.usage.total&&t.usage.total.cacheReadTokens||0)),1)])):y("",!0)]),e("div",Ea,[e("div",Pa,[s[89]||(s[89]=e("span",{class:"text-gray-600"},"今日请求:",-1)),e("span",Ua,u(W(t.usage&&t.usage.daily&&t.usage.daily.requests||0))+" 次",1)]),e("div",Va,[s[90]||(s[90]=e("span",{class:"text-gray-600"},"今日 Token:",-1)),e("span",Ga,u(W(t.usage&&t.usage.daily&&t.usage.daily.tokens||0)),1)])])])])):y("",!0)]))),128))])):y("",!0),F.value.length>0?(n(),i("div",Oa,[e("div",qa,[e("span",Fa," 共 "+u(F.value.length)+" 条记录 ",1),e("div",Wa,[s[92]||(s[92]=e("span",{class:"text-xs sm:text-sm text-gray-600"},"每页显示",-1)),D(e("select",{"onUpdate:modelValue":s[9]||(s[9]=t=>p.value=t),class:"px-2 py-1 text-xs sm:text-sm text-gray-700 bg-white border border-gray-200 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent hover:border-gray-300 transition-colors",onChange:s[10]||(s[10]=t=>x.value=1)},[(n(),i(R,null,G(Y,t=>e("option",{key:t,value:t},u(t),9,za)),64))],544),[[le,p.value]]),s[93]||(s[93]=e("span",{class:"text-xs sm:text-sm text-gray-600"},"条",-1))])]),e("div",Na,[e("button",{class:"px-3 py-1.5 sm:py-1 text-xs sm:text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",disabled:x.value===1,onClick:s[11]||(s[11]=t=>x.value--)},s[94]||(s[94]=[e("i",{class:"fas fa-chevron-left"},null,-1)]),8,Ya),e("div",Ba,[x.value>3?(n(),i("button",{key:0,class:"hidden sm:block px-3 py-1 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50",onClick:s[12]||(s[12]=t=>x.value=1)}," 1 ")):y("",!0),x.value>4?(n(),i("span",Ha,"...")):y("",!0),(n(!0),i(R,null,G(se.value,t=>(n(),i("button",{key:t,class:P(["px-2 sm:px-3 py-1 text-xs sm:text-sm font-medium rounded-md",t===x.value?"bg-blue-600 text-white":"text-gray-700 bg-white border border-gray-300 hover:bg-gray-50"]),onClick:g=>x.value=t},u(t),11,Qa))),128)),x.value<Q.value-3?(n(),i("span",Xa,"...")):y("",!0),Q.value>1&&x.value<Q.value-2?(n(),i("button",{key:3,class:"hidden sm:block px-3 py-1 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50",onClick:s[13]||(s[13]=t=>x.value=Q.value)},u(Q.value),1)):y("",!0)]),e("button",{class:"px-3 py-1.5 sm:py-1 text-xs sm:text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",disabled:x.value===Q.value||Q.value===0,onClick:s[14]||(s[14]=t=>x.value++)},s[95]||(s[95]=[e("i",{class:"fas fa-chevron-right"},null,-1)]),8,Ja)])])):y("",!0)]),H.value?(n(),Z(xs,{key:0,accounts:w.value,onClose:s[15]||(s[15]=t=>H.value=!1),onSuccess:Fe,onBatchSuccess:We},null,8,["accounts"])):y("",!0),T.value?(n(),Z(yl,{key:1,"api-key":te.value,accounts:w.value,onClose:s[16]||(s[16]=t=>T.value=!1),onSuccess:ze},null,8,["api-key","accounts"])):y("",!0),a.value?(n(),Z(jl,{key:2,"api-key":_.value,onClose:s[17]||(s[17]=t=>a.value=!1),onSuccess:Ne},null,8,["api-key"])):y("",!0),m.value?(n(),Z(Bl,{key:3,"api-key":o.value,onClose:s[18]||(s[18]=t=>m.value=!1)},null,8,["api-key"])):y("",!0),B.value?(n(),Z(wo,{key:4,"api-keys":r.value,onClose:s[19]||(s[19]=t=>B.value=!1)},null,8,["api-keys"])):y("",!0),Se(Fo,{ref_key:"expiryEditModalRef",ref:d,show:!!k.value,"api-key":k.value||{id:null,expiresAt:null,name:""},onClose:Te,onSave:He},null,8,["show","api-key"])])}}},nr=ae(Za,[["__scopeId","data-v-9c252b1b"]]);export{nr as default};
|