Files
claude-relay-service/web/admin-spa/dist/assets/AccountsView-DHI8l47P.js

16 lines
90 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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

import{r as b,aR as ze,o as E,V as Ee,x as n,y as a,z as e,L as y,K as g,al as _e,aY as Ce,aX as me,aq as _,aZ as Oe,C as K,O as $,c as ne,P as f,I as le,a5 as Ae,q as Re,an as X,Q as re,ac as ie,R as $e,u as Y,Y as We,B as Te}from"./vue-vendor-CKToUHZx.js";import{s as h}from"./toast-BvwA7Mwb.js";import{a as V,_ as qe}from"./index-D1PUfDNP.js";import"./element-plus-B8Fs_0jW.js";import"./vendor-BDiMbLwQ.js";const he=b(!1),Me=b({title:"",message:"",confirmText:"继续",cancelText:"取消"}),se=b(null);function Le(){return{showConfirmModal:he,confirmOptions:Me,showConfirm:(C,i,M="继续",I="取消")=>new Promise(T=>{Me.value={title:C,message:i,confirmText:M,cancelText:I},se.value=T,he.value=!0}),handleConfirm:()=>{he.value=!1,se.value&&(se.value(!0),se.value=null)},handleCancel:()=>{he.value=!1,se.value&&(se.value(!1),se.value=null)}}}const Pe=ze("accounts",()=>{const P=b([]),O=b([]),d=b([]),C=b(!1),i=b(null),M=b(""),I=b("asc"),T=async()=>{C.value=!0,i.value=null;try{const c=await V.get("/admin/claude-accounts");if(c.success)P.value=c.data||[];else throw new Error(c.message||"获取Claude账户失败")}catch(c){throw i.value=c.message,c}finally{C.value=!1}},w=async()=>{C.value=!0,i.value=null;try{const c=await V.get("/admin/claude-console-accounts");if(c.success)O.value=c.data||[];else throw new Error(c.message||"获取Claude Console账户失败")}catch(c){throw i.value=c.message,c}finally{C.value=!1}},v=async()=>{C.value=!0,i.value=null;try{const c=await V.get("/admin/gemini-accounts");if(c.success)d.value=c.data||[];else throw new Error(c.message||"获取Gemini账户失败")}catch(c){throw i.value=c.message,c}finally{C.value=!1}};return{claudeAccounts:P,claudeConsoleAccounts:O,geminiAccounts:d,loading:C,error:i,sortBy:M,sortOrder:I,fetchClaudeAccounts:T,fetchClaudeConsoleAccounts:w,fetchGeminiAccounts:v,fetchAllAccounts:async()=>{C.value=!0,i.value=null;try{await Promise.all([T(),w(),v()])}catch(c){throw i.value=c.message,c}finally{C.value=!1}},createClaudeAccount:async c=>{C.value=!0,i.value=null;try{const p=await V.post("/admin/claude-accounts",c);if(p.success)return await T(),p.data;throw new Error(p.message||"创建Claude账户失败")}catch(p){throw i.value=p.message,p}finally{C.value=!1}},createClaudeConsoleAccount:async c=>{C.value=!0,i.value=null;try{const p=await V.post("/admin/claude-console-accounts",c);if(p.success)return await w(),p.data;throw new Error(p.message||"创建Claude Console账户失败")}catch(p){throw i.value=p.message,p}finally{C.value=!1}},createGeminiAccount:async c=>{C.value=!0,i.value=null;try{const p=await V.post("/admin/gemini-accounts",c);if(p.success)return await v(),p.data;throw new Error(p.message||"创建Gemini账户失败")}catch(p){throw i.value=p.message,p}finally{C.value=!1}},updateClaudeAccount:async(c,p)=>{C.value=!0,i.value=null;try{const U=await V.put(`/admin/claude-accounts/${c}`,p);if(U.success)return await T(),U;throw new Error(U.message||"更新Claude账户失败")}catch(U){throw i.value=U.message,U}finally{C.value=!1}},updateClaudeConsoleAccount:async(c,p)=>{C.value=!0,i.value=null;try{const U=await V.put(`/admin/claude-console-accounts/${c}`,p);if(U.success)return await w(),U;throw new Error(U.message||"更新Claude Console账户失败")}catch(U){throw i.value=U.message,U}finally{C.value=!1}},updateGeminiAccount:async(c,p)=>{C.value=!0,i.value=null;try{const U=await V.put(`/admin/gemini-accounts/${c}`,p);if(U.success)return await v(),U;throw new Error(U.message||"更新Gemini账户失败")}catch(U){throw i.value=U.message,U}finally{C.value=!1}},toggleAccount:async(c,p)=>{C.value=!0,i.value=null;try{let U;c==="claude"?U=`/admin/claude-accounts/${p}/toggle`:c==="claude-console"?U=`/admin/claude-console-accounts/${p}/toggle`:U=`/admin/gemini-accounts/${p}/toggle`;const F=await V.put(U);if(F.success)return c==="claude"?await T():c==="claude-console"?await w():await v(),F;throw new Error(F.message||"切换状态失败")}catch(U){throw i.value=U.message,U}finally{C.value=!1}},deleteAccount:async(c,p)=>{C.value=!0,i.value=null;try{let U;c==="claude"?U=`/admin/claude-accounts/${p}`:c==="claude-console"?U=`/admin/claude-console-accounts/${p}`:U=`/admin/gemini-accounts/${p}`;const F=await V.delete(U);if(F.success)return c==="claude"?await T():c==="claude-console"?await w():await v(),F;throw new Error(F.message||"删除失败")}catch(U){throw i.value=U.message,U}finally{C.value=!1}},refreshClaudeToken:async c=>{C.value=!0,i.value=null;try{const p=await V.post(`/admin/claude-accounts/${c}/refresh`);if(p.success)return await T(),p;throw new Error(p.message||"Token刷新失败")}catch(p){throw i.value=p.message,p}finally{C.value=!1}},generateClaudeAuthUrl:async c=>{try{const p=await V.post("/admin/claude-accounts/generate-auth-url",c);if(p.success)return p.data;throw new Error(p.message||"生成授权URL失败")}catch(p){throw i.value=p.message,p}},exchangeClaudeCode:async c=>{try{const p=await V.post("/admin/claude-accounts/exchange-code",c);if(p.success)return p.data;throw new Error(p.message||"交换授权码失败")}catch(p){throw i.value=p.message,p}},generateGeminiAuthUrl:async c=>{try{const p=await V.post("/admin/gemini-accounts/generate-auth-url",c);if(p.success)return p.data;throw new Error(p.message||"生成授权URL失败")}catch(p){throw i.value=p.message,p}},exchangeGeminiCode:async c=>{try{const p=await V.post("/admin/gemini-accounts/exchange-code",c);if(p.success)return p.data;throw new Error(p.message||"交换授权码失败")}catch(p){throw i.value=p.message,p}},sortAccounts:c=>{M.value===c?I.value=I.value==="asc"?"desc":"asc":(M.value=c,I.value="asc")},reset:()=>{P.value=[],O.value=[],d.value=[],C.value=!1,i.value=null,M.value="",I.value="asc"}}}),Be={class:"space-y-4"},Fe={class:"flex items-center justify-between"},Ne={class:"flex items-center cursor-pointer"},He={key:0,class:"bg-gray-50 p-4 rounded-lg border border-gray-200 space-y-4"},Je={class:"grid grid-cols-2 gap-4"},Ye={class:"space-y-4"},Qe={class:"flex items-center"},Xe={key:0,class:"grid grid-cols-2 gap-4"},Ze={class:"relative"},et=["type"],Ge={__name:"ProxyConfig",props:{modelValue:{type:Object,default:()=>({enabled:!1,type:"socks5",host:"",port:"",username:"",password:""})}},emits:["update:modelValue"],setup(P,{emit:O}){const d=P,C=O,i=b({...d.modelValue}),M=b(!!(i.value.username||i.value.password)),I=b(!1);E(()=>d.modelValue,v=>{JSON.stringify(v)!==JSON.stringify(i.value)&&(i.value={...v},M.value=!!(v.username||v.password))},{deep:!0}),E(()=>i.value.enabled,v=>{w()}),E(()=>i.value.type,v=>{w()}),E(()=>i.value.host,v=>{w()}),E(()=>i.value.port,v=>{w()}),E(()=>i.value.username,v=>{w()}),E(()=>i.value.password,v=>{w()}),E(M,v=>{v||(i.value.username="",i.value.password="",w())});let T=null;function w(){T&&clearTimeout(T),T=setTimeout(()=>{const v={...i.value};M.value||(v.username="",v.password=""),C("update:modelValue",v)},100)}return Ee(()=>{T&&clearTimeout(T)}),(v,m)=>(a(),n("div",Be,[e("div",Fe,[m[9]||(m[9]=e("h4",{class:"text-sm font-semibold text-gray-700"}," 代理设置 (可选) ",-1)),e("label",Ne,[g(e("input",{"onUpdate:modelValue":m[0]||(m[0]=G=>i.value.enabled=G),type:"checkbox",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[_e,i.value.enabled]]),m[8]||(m[8]=e("span",{class:"ml-2 text-sm text-gray-700"},"启用代理",-1))])]),i.value.enabled?(a(),n("div",He,[m[17]||(m[17]=Ce('<div class="flex items-start gap-3 mb-3"><div class="w-8 h-8 bg-gray-500 rounded-lg flex items-center justify-center flex-shrink-0"><i class="fas fa-server text-white text-sm"></i></div><div class="flex-1"><p class="text-sm text-gray-700"> 配置代理以访问受限的网络资源。支持 SOCKS5 和 HTTP 代理。 </p><p class="text-xs text-gray-500 mt-1"> 请确保代理服务器稳定可用,否则会影响账户的正常使用。 </p></div></div>',1)),e("div",null,[m[11]||(m[11]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"代理类型",-1)),g(e("select",{"onUpdate:modelValue":m[1]||(m[1]=G=>i.value.type=G),class:"form-input w-full"},m[10]||(m[10]=[e("option",{value:"socks5"}," SOCKS5 ",-1),e("option",{value:"http"}," HTTP ",-1),e("option",{value:"https"}," HTTPS ",-1)]),512),[[me,i.value.type]])]),e("div",Je,[e("div",null,[m[12]||(m[12]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"主机地址",-1)),g(e("input",{"onUpdate:modelValue":m[2]||(m[2]=G=>i.value.host=G),type:"text",placeholder:"例如: 192.168.1.100",class:"form-input w-full"},null,512),[[_,i.value.host]])]),e("div",null,[m[13]||(m[13]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"端口",-1)),g(e("input",{"onUpdate:modelValue":m[3]||(m[3]=G=>i.value.port=G),type:"number",placeholder:"例如: 1080",class:"form-input w-full"},null,512),[[_,i.value.port]])])]),e("div",Ye,[e("div",Qe,[g(e("input",{id:"proxyAuth","onUpdate:modelValue":m[4]||(m[4]=G=>M.value=G),type:"checkbox",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[_e,M.value]]),m[14]||(m[14]=e("label",{for:"proxyAuth",class:"ml-2 text-sm text-gray-700 cursor-pointer"}," 需要身份验证 ",-1))]),M.value?(a(),n("div",Xe,[e("div",null,[m[15]||(m[15]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"用户名",-1)),g(e("input",{"onUpdate:modelValue":m[5]||(m[5]=G=>i.value.username=G),type:"text",placeholder:"代理用户名",class:"form-input w-full"},null,512),[[_,i.value.username]])]),e("div",null,[m[16]||(m[16]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"密码",-1)),e("div",Ze,[g(e("input",{"onUpdate:modelValue":m[6]||(m[6]=G=>i.value.password=G),type:I.value?"text":"password",placeholder:"代理密码",class:"form-input w-full pr-10"},null,8,et),[[Oe,i.value.password]]),e("button",{type:"button",class:"absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-gray-600",onClick:m[7]||(m[7]=G=>I.value=!I.value)},[e("i",{class:K(I.value?"fas fa-eye-slash":"fas fa-eye")},null,2)])])])])):y("",!0)]),m[18]||(m[18]=e("div",{class:"bg-blue-50 p-3 rounded-lg border border-blue-200"},[e("p",{class:"text-xs text-blue-700"},[e("i",{class:"fas fa-info-circle mr-1"}),e("strong",null,"提示:"),$("代理设置将用于所有与此账户相关的API请求。请确保代理服务器支持HTTPS流量转发。 ")])],-1))])):y("",!0)]))}},tt={class:"space-y-6"},st={key:0},lt={class:"bg-blue-50 p-6 rounded-lg border border-blue-200"},ot={class:"flex items-start gap-4"},at={class:"flex-1"},nt={class:"space-y-4"},rt={class:"bg-white/80 rounded-lg p-4 border border-blue-300"},it={class:"flex items-start gap-3"},ut={class:"flex-1"},dt=["disabled"],pt={key:0,class:"fas fa-link mr-2"},mt={key:1,class:"loading-spinner mr-2"},ct={key:1,class:"space-y-3"},ft={class:"flex items-center gap-2"},xt=["value"],vt={class:"bg-white/80 rounded-lg p-4 border border-blue-300"},gt={class:"flex items-start gap-3"},yt={class:"flex-1"},bt={class:"space-y-3"},wt={key:1},kt={class:"bg-green-50 p-6 rounded-lg border border-green-200"},ht={class:"flex items-start gap-4"},$t={class:"flex-1"},Ct={class:"space-y-4"},Tt={class:"bg-white/80 rounded-lg p-4 border border-green-300"},At={class:"flex items-start gap-3"},Ut={class:"flex-1"},It=["disabled"],Vt={key:0,class:"fas fa-link mr-2"},jt={key:1,class:"loading-spinner mr-2"},St={key:1,class:"space-y-3"},_t={class:"flex items-center gap-2"},Mt=["value"],Gt={class:"bg-white/80 rounded-lg p-4 border border-green-300"},Kt={class:"flex items-start gap-3"},Rt={class:"flex-1"},Lt={class:"space-y-3"},Pt={class:"flex gap-3 pt-4"},Dt=["disabled"],zt={key:0,class:"loading-spinner mr-2"},Et={__name:"OAuthFlow",props:{platform:{type:String,required:!0},proxy:{type:Object,default:null}},emits:["success","back"],setup(P,{emit:O}){const d=P,C=O,i=Pe(),M=b(!1),I=b(!1),T=b(""),w=b(""),v=b(!1),m=b(""),G=ne(()=>T.value&&w.value.trim());E(w,x=>{if(!x||typeof x!="string")return;const r=x.trim();if(!r)return;if(r.startsWith("http://")||r.startsWith("https://"))if(r.startsWith("http://localhost:45462"))try{const W=new URL(r).searchParams.get("code");W?(w.value=W,h("成功提取授权码!","success"),console.log("Successfully extracted authorization code from URL")):h("URL 中未找到授权码参数,请检查链接是否正确","error")}catch(B){console.error("Failed to parse URL:",B),h("链接格式错误,请检查是否为完整的 URL","error")}else if(d.platform==="gemini")try{const W=new URL(r).searchParams.get("code");W&&(w.value=W,h("成功提取授权码!","success"))}catch{}else h("请粘贴以 http://localhost:45462 开头的链接","error")});const S=async()=>{var x;M.value=!0;try{const r=(x=d.proxy)!=null&&x.enabled?{proxy:{type:d.proxy.type,host:d.proxy.host,port:parseInt(d.proxy.port),username:d.proxy.username||null,password:d.proxy.password||null}}:{};if(d.platform==="claude"){const L=await i.generateClaudeAuthUrl(r);T.value=L.authUrl,m.value=L.sessionId}else if(d.platform==="gemini"){const L=await i.generateGeminiAuthUrl(r);T.value=L.authUrl,m.value=L.sessionId}}catch(r){h(r.message||"生成授权链接失败","error")}finally{M.value=!1}},R=()=>{T.value="",w.value="",S()},q=async()=>{try{await navigator.clipboard.writeText(T.value),v.value=!0,h("链接已复制","success"),setTimeout(()=>{v.value=!1},2e3)}catch{const r=document.createElement("input");r.value=T.value,document.body.appendChild(r),r.select(),document.execCommand("copy"),document.body.removeChild(r),v.value=!0,h("链接已复制","success"),setTimeout(()=>{v.value=!1},2e3)}},l=async()=>{var x;if(G.value){I.value=!0;try{let r={};d.platform==="claude"?r={sessionId:m.value,callbackUrl:w.value.trim()}:d.platform==="gemini"&&(r={code:w.value.trim(),sessionId:m.value}),(x=d.proxy)!=null&&x.enabled&&(r.proxy={type:d.proxy.type,host:d.proxy.host,port:parseInt(d.proxy.port),username:d.proxy.username||null,password:d.proxy.password||null});let L;d.platform==="claude"?L=await i.exchangeClaudeCode(r):d.platform==="gemini"&&(L=await i.exchangeGeminiCode(r)),C("success",L)}catch(r){h(r.message||"授权失败,请检查授权码是否正确","error")}finally{I.value=!1}}};return(x,r)=>(a(),n("div",tt,[P.platform==="claude"?(a(),n("div",st,[e("div",lt,[e("div",ot,[r[14]||(r[14]=e("div",{class:"w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center flex-shrink-0"},[e("i",{class:"fas fa-link text-white"})],-1)),e("div",at,[r[12]||(r[12]=e("h4",{class:"font-semibold text-blue-900 mb-3"}," Claude 账户授权 ",-1)),r[13]||(r[13]=e("p",{class:"text-sm text-blue-800 mb-4"}," 请按照以下步骤完成 Claude 账户的授权: ",-1)),e("div",nt,[e("div",rt,[e("div",it,[r[5]||(r[5]=e("div",{class:"w-6 h-6 bg-blue-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"}," 1 ",-1)),e("div",ut,[r[4]||(r[4]=e("p",{class:"font-medium text-blue-900 mb-2"}," 点击下方按钮生成授权链接 ",-1)),T.value?(a(),n("div",ct,[e("div",ft,[e("input",{type:"text",value:T.value,readonly:"",class:"form-input flex-1 text-xs font-mono bg-gray-50"},null,8,xt),e("button",{class:"px-3 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors",title:"复制链接",onClick:q},[e("i",{class:K(v.value?"fas fa-check text-green-500":"fas fa-copy")},null,2)])]),e("button",{class:"text-xs text-blue-600 hover:text-blue-700",onClick:R},r[3]||(r[3]=[e("i",{class:"fas fa-sync-alt mr-1"},null,-1),$("重新生成 ",-1)]))])):(a(),n("button",{key:0,disabled:M.value,class:"btn btn-primary px-4 py-2 text-sm",onClick:S},[M.value?(a(),n("div",mt)):(a(),n("i",pt)),$(" "+f(M.value?"生成中...":"生成授权链接"),1)],8,dt))])])]),r[11]||(r[11]=Ce('<div class="bg-white/80 rounded-lg p-4 border border-blue-300"><div class="flex items-start gap-3"><div class="w-6 h-6 bg-blue-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"> 2 </div><div class="flex-1"><p class="font-medium text-blue-900 mb-2"> 在浏览器中打开链接并完成授权 </p><p class="text-sm text-blue-700 mb-2"> 请在新标签页中打开授权链接,登录您的 Claude 账户并授权。 </p><div class="bg-yellow-50 p-3 rounded border border-yellow-300"><p class="text-xs text-yellow-800"><i class="fas fa-exclamation-triangle mr-1"></i><strong>注意:</strong>如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。 </p></div></div></div></div>',1)),e("div",vt,[e("div",gt,[r[10]||(r[10]=e("div",{class:"w-6 h-6 bg-blue-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"}," 3 ",-1)),e("div",yt,[r[8]||(r[8]=e("p",{class:"font-medium text-blue-900 mb-2"}," 输入 Authorization Code ",-1)),r[9]||(r[9]=e("p",{class:"text-sm text-blue-700 mb-3"},[$(" 授权完成后,页面会显示一个 "),e("strong",null,"Authorization Code"),$(",请将其复制并粘贴到下方输入框: ")],-1)),e("div",bt,[e("div",null,[r[6]||(r[6]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},[e("i",{class:"fas fa-key text-blue-500 mr-2"}),$("Authorization Code ")],-1)),g(e("textarea",{"onUpdate:modelValue":r[0]||(r[0]=L=>w.value=L),rows:"3",class:"form-input w-full resize-none font-mono text-sm",placeholder:"粘贴从Claude页面获取的Authorization Code..."},null,512),[[_,w.value]])]),r[7]||(r[7]=e("p",{class:"text-xs text-gray-500 mt-2"},[e("i",{class:"fas fa-info-circle mr-1"}),$(" 请粘贴从Claude页面复制的Authorization Code ")],-1))])])])])])])])])])):P.platform==="gemini"?(a(),n("div",wt,[e("div",kt,[e("div",ht,[r[26]||(r[26]=e("div",{class:"w-10 h-10 bg-green-500 rounded-lg flex items-center justify-center flex-shrink-0"},[e("i",{class:"fas fa-robot text-white"})],-1)),e("div",$t,[r[24]||(r[24]=e("h4",{class:"font-semibold text-green-900 mb-3"}," Gemini 账户授权 ",-1)),r[25]||(r[25]=e("p",{class:"text-sm text-green-800 mb-4"}," 请按照以下步骤完成 Gemini 账户的授权: ",-1)),e("div",Ct,[e("div",Tt,[e("div",At,[r[17]||(r[17]=e("div",{class:"w-6 h-6 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"}," 1 ",-1)),e("div",Ut,[r[16]||(r[16]=e("p",{class:"font-medium text-green-900 mb-2"}," 点击下方按钮生成授权链接 ",-1)),T.value?(a(),n("div",St,[e("div",_t,[e("input",{type:"text",value:T.value,readonly:"",class:"form-input flex-1 text-xs font-mono bg-gray-50"},null,8,Mt),e("button",{class:"px-3 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors",title:"复制链接",onClick:q},[e("i",{class:K(v.value?"fas fa-check text-green-500":"fas fa-copy")},null,2)])]),e("button",{class:"text-xs text-green-600 hover:text-green-700",onClick:R},r[15]||(r[15]=[e("i",{class:"fas fa-sync-alt mr-1"},null,-1),$("重新生成 ",-1)]))])):(a(),n("button",{key:0,disabled:M.value,class:"btn btn-primary px-4 py-2 text-sm",onClick:S},[M.value?(a(),n("div",jt)):(a(),n("i",Vt)),$(" "+f(M.value?"生成中...":"生成授权链接"),1)],8,It))])])]),r[23]||(r[23]=Ce('<div class="bg-white/80 rounded-lg p-4 border border-green-300"><div class="flex items-start gap-3"><div class="w-6 h-6 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"> 2 </div><div class="flex-1"><p class="font-medium text-blue-900 mb-2"> 在浏览器中打开链接并完成授权 </p><p class="text-sm text-blue-700 mb-2"> 请在新标签页中打开授权链接,登录您的 Gemini 账户并授权。 </p><div class="bg-yellow-50 p-3 rounded border border-yellow-300"><p class="text-xs text-yellow-800"><i class="fas fa-exclamation-triangle mr-1"></i><strong>注意:</strong>如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。 </p></div></div></div></div>',1)),e("div",Gt,[e("div",Kt,[r[22]||(r[22]=e("div",{class:"w-6 h-6 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"}," 3 ",-1)),e("div",Rt,[r[20]||(r[20]=e("p",{class:"font-medium text-green-900 mb-2"}," 输入 Authorization Code ",-1)),r[21]||(r[21]=e("p",{class:"text-sm text-green-700 mb-3"}," 授权完成后,页面会显示一个 Authorization Code请将其复制并粘贴到下方输入框 ",-1)),e("div",Lt,[e("div",null,[r[18]||(r[18]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},[e("i",{class:"fas fa-key text-green-500 mr-2"}),$("Authorization Code ")],-1)),g(e("textarea",{"onUpdate:modelValue":r[1]||(r[1]=L=>w.value=L),rows:"3",class:"form-input w-full resize-none font-mono text-sm",placeholder:"粘贴从Gemini页面获取的Authorization Code..."},null,512),[[_,w.value]])]),r[19]||(r[19]=e("div",{class:"mt-2 space-y-1"},[e("p",{class:"text-xs text-gray-600"},[e("i",{class:"fas fa-check-circle text-green-500 mr-1"}),$(" 请粘贴从Gemini页面复制的Authorization Code ")])],-1))])])])])])])])])])):y("",!0),e("div",Pt,[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:r[2]||(r[2]=L=>x.$emit("back"))}," 上一步 "),e("button",{type:"button",disabled:!G.value||I.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold",onClick:l},[I.value?(a(),n("div",zt)):y("",!0),$(" "+f(I.value?"验证中...":"完成授权"),1)],8,Dt)])]))}},Ot={key:0,class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},Wt={class:"modal-content w-full max-w-md p-6 mx-auto"},qt={class:"flex items-start gap-4 mb-6"},Bt={class:"flex-1"},Ft={class:"text-lg font-bold text-gray-900 mb-2"},Nt={class:"text-gray-600 text-sm leading-relaxed whitespace-pre-line"},Ht={class:"flex gap-3"},De={__name:"ConfirmModal",props:{show:{type:Boolean,required:!0},title:{type:String,default:""},message:{type:String,default:""},confirmText:{type:String,default:"继续"},cancelText:{type:String,default:"取消"}},emits:["confirm","cancel"],setup(P){return(O,d)=>(a(),le(Ae,{to:"body"},[P.show?(a(),n("div",Ot,[e("div",Wt,[e("div",qt,[d[2]||(d[2]=e("div",{class:"w-12 h-12 bg-gradient-to-br from-yellow-400 to-yellow-500 rounded-full flex items-center justify-center flex-shrink-0"},[e("i",{class:"fas fa-exclamation text-white text-xl"})],-1)),e("div",Bt,[e("h3",Ft,f(P.title),1),e("p",Nt,f(P.message),1)])]),e("div",Ht,[e("button",{class:"flex-1 px-4 py-2.5 bg-gray-100 text-gray-700 rounded-xl font-medium hover:bg-gray-200 transition-colors",onClick:d[0]||(d[0]=C=>O.$emit("cancel"))},f(P.cancelText),1),e("button",{class:"flex-1 px-4 py-2.5 bg-gradient-to-r from-yellow-500 to-orange-500 text-white rounded-xl font-medium hover:from-yellow-600 hover:to-orange-600 transition-colors shadow-sm",onClick:d[1]||(d[1]=C=>O.$emit("confirm"))},f(P.confirmText),1)])])])):y("",!0)]))}},Jt={key:0,class:"fixed inset-0 modal z-50 flex items-center justify-center p-3 sm:p-4"},Yt={class:"modal-content w-full max-w-4xl p-4 sm:p-6 md:p-8 mx-auto max-h-[90vh] overflow-y-auto custom-scrollbar"},Qt={class:"flex items-center justify-between mb-4 sm:mb-6"},Xt={class:"mb-6"},Zt={key:0,class:"mb-6 p-4 bg-blue-50 rounded-lg border border-blue-200"},es={class:"space-y-4"},ts={class:"flex gap-4"},ss={class:"flex items-center cursor-pointer"},ls={class:"flex items-center cursor-pointer"},os={class:"flex gap-3"},as=["disabled"],ns={key:0,class:"loading-spinner mr-2"},rs={class:"space-y-4"},is={key:0,class:"text-center py-8"},us={key:1,class:"text-center py-8 bg-gray-50 rounded-lg"},ds={key:2,class:"grid gap-4 grid-cols-1 md:grid-cols-2"},ps={class:"flex items-start justify-between mb-3"},ms={class:"flex-1"},cs={class:"font-semibold text-gray-900"},fs={class:"text-sm text-gray-500 mt-1"},xs={class:"flex items-center gap-2 ml-4"},vs={class:"flex items-center justify-between text-sm text-gray-600"},gs={class:"flex items-center gap-4"},ys={class:"flex items-center gap-2"},bs=["onClick"],ws=["disabled","onClick"],ks={key:1,class:"fixed inset-0 modal z-60 flex items-center justify-center p-3 sm:p-4"},hs={class:"modal-content w-full max-w-lg p-4 sm:p-6"},$s={class:"space-y-4"},Cs={class:"px-3 py-2 bg-gray-100 rounded-lg text-sm text-gray-600"},Ts={class:"flex gap-3 pt-4"},As=["disabled"],Us={key:0,class:"loading-spinner mr-2"},Is={__name:"GroupManagementModal",emits:["close","refresh"],setup(P,{emit:O}){const d=O,C=b(!0),i=b(!1),M=b([]),I=b(!1),T=b(!1),w=b({name:"",platform:"claude",description:""}),v=b(!1),m=b(!1),G=b(null),S=b({name:"",platform:"",description:""}),R=j=>j?new Date(j).toLocaleDateString("zh-CN"):"-",q=async()=>{i.value=!0;try{const j=await V.get("/admin/account-groups");M.value=j.data||[]}catch{h("加载分组列表失败","error")}finally{i.value=!1}},l=async()=>{var j,u;if(!w.value.name||!w.value.platform){h("请填写必填项","error");return}T.value=!0;try{await V.post("/admin/account-groups",{name:w.value.name,platform:w.value.platform,description:w.value.description}),h("分组创建成功","success"),x(),await q(),d("refresh")}catch(A){h(((u=(j=A.response)==null?void 0:j.data)==null?void 0:u.error)||"创建分组失败","error")}finally{T.value=!1}},x=()=>{I.value=!1,w.value={name:"",platform:"claude",description:""}},r=j=>{G.value=j,S.value={name:j.name,platform:j.platform,description:j.description||""},v.value=!0},L=async()=>{var j,u;if(!S.value.name){h("请填写分组名称","error");return}m.value=!0;try{await V.put(`/admin/account-groups/${G.value.id}`,{name:S.value.name,description:S.value.description}),h("分组更新成功","success"),B(),await q(),d("refresh")}catch(A){h(((u=(j=A.response)==null?void 0:j.data)==null?void 0:u.error)||"更新分组失败","error")}finally{m.value=!1}},B=()=>{v.value=!1,G.value=null,S.value={name:"",platform:"",description:""}},W=async j=>{var u,A;if(j.memberCount>0){h("分组内还有成员,无法删除","error");return}if(confirm(`确定要删除分组 "${j.name}" 吗?`))try{await V.delete(`/admin/account-groups/${j.id}`),h("分组删除成功","success"),await q(),d("refresh")}catch(Z){h(((A=(u=Z.response)==null?void 0:u.data)==null?void 0:A.error)||"删除分组失败","error")}};return Re(()=>{q()}),(j,u)=>(a(),le(Ae,{to:"body"},[C.value?(a(),n("div",Jt,[e("div",Yt,[e("div",Qt,[u[9]||(u[9]=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-purple-500 to-purple-600 rounded-lg sm:rounded-xl flex items-center justify-center"},[e("i",{class:"fas fa-layer-group text-white text-sm sm:text-base"})]),e("h3",{class:"text-lg sm:text-xl font-bold text-gray-900"}," 账户分组管理 ")],-1)),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors p-1",onClick:u[0]||(u[0]=A=>j.$emit("close"))},u[8]||(u[8]=[e("i",{class:"fas fa-times text-lg sm:text-xl"},null,-1)]))]),e("div",Xt,[e("button",{class:"btn btn-primary px-4 py-2",onClick:u[1]||(u[1]=A=>I.value=!0)},u[10]||(u[10]=[e("i",{class:"fas fa-plus mr-2"},null,-1),$(" 创建新分组 ",-1)]))]),I.value?(a(),n("div",Zt,[u[16]||(u[16]=e("h4",{class:"text-lg font-semibold text-gray-900 mb-4"},"创建新分组",-1)),e("div",es,[e("div",null,[u[11]||(u[11]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"分组名称 *",-1)),g(e("input",{"onUpdate:modelValue":u[2]||(u[2]=A=>w.value.name=A),type:"text",class:"form-input w-full",placeholder:"输入分组名称"},null,512),[[_,w.value.name]])]),e("div",null,[u[14]||(u[14]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"平台类型 *",-1)),e("div",ts,[e("label",ss,[g(e("input",{"onUpdate:modelValue":u[3]||(u[3]=A=>w.value.platform=A),type:"radio",value:"claude",class:"mr-2"},null,512),[[X,w.value.platform]]),u[12]||(u[12]=e("span",{class:"text-sm text-gray-700"},"Claude",-1))]),e("label",ls,[g(e("input",{"onUpdate:modelValue":u[4]||(u[4]=A=>w.value.platform=A),type:"radio",value:"gemini",class:"mr-2"},null,512),[[X,w.value.platform]]),u[13]||(u[13]=e("span",{class:"text-sm text-gray-700"},"Gemini",-1))])])]),e("div",null,[u[15]||(u[15]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"描述 (可选)",-1)),g(e("textarea",{"onUpdate:modelValue":u[5]||(u[5]=A=>w.value.description=A),rows:"2",class:"form-input w-full resize-none",placeholder:"分组描述..."},null,512),[[_,w.value.description]])]),e("div",os,[e("button",{class:"btn btn-primary px-4 py-2",disabled:!w.value.name||!w.value.platform||T.value,onClick:l},[T.value?(a(),n("div",ns)):y("",!0),$(" "+f(T.value?"创建中...":"创建"),1)],8,as),e("button",{class:"btn btn-secondary px-4 py-2",onClick:x}," 取消 ")])])])):y("",!0),e("div",rs,[i.value?(a(),n("div",is,u[17]||(u[17]=[e("div",{class:"loading-spinner-lg mx-auto mb-4"},null,-1),e("p",{class:"text-gray-500"},"加载中...",-1)]))):M.value.length===0?(a(),n("div",us,u[18]||(u[18]=[e("i",{class:"fas fa-layer-group text-4xl text-gray-300 mb-4"},null,-1),e("p",{class:"text-gray-500"},"暂无分组",-1)]))):(a(),n("div",ds,[(a(!0),n(re,null,ie(M.value,A=>(a(),n("div",{key:A.id,class:"bg-white rounded-lg border p-4 hover:shadow-md transition-shadow"},[e("div",ps,[e("div",ms,[e("h4",cs,f(A.name),1),e("p",fs,f(A.description||"暂无描述"),1)]),e("div",xs,[e("span",{class:K(["px-2 py-1 text-xs font-medium rounded-full",A.platform==="claude"?"bg-purple-100 text-purple-700":"bg-blue-100 text-blue-700"])},f(A.platform==="claude"?"Claude":"Gemini"),3)])]),e("div",vs,[e("div",gs,[e("span",null,[u[19]||(u[19]=e("i",{class:"fas fa-users mr-1"},null,-1)),$(" "+f(A.memberCount||0)+" 个成员 ",1)]),e("span",null,[u[20]||(u[20]=e("i",{class:"fas fa-clock mr-1"},null,-1)),$(" "+f(R(A.createdAt)),1)])]),e("div",ys,[e("button",{class:"text-blue-600 hover:text-blue-800 transition-colors",title:"编辑",onClick:Z=>r(A)},u[21]||(u[21]=[e("i",{class:"fas fa-edit"},null,-1)]),8,bs),e("button",{class:"text-red-600 hover:text-red-800 transition-colors",title:"删除",disabled:A.memberCount>0,onClick:Z=>W(A)},u[22]||(u[22]=[e("i",{class:"fas fa-trash"},null,-1)]),8,ws)])])]))),128))]))])])])):y("",!0),v.value?(a(),n("div",ks,[e("div",hs,[e("div",{class:"flex items-center justify-between mb-4"},[u[24]||(u[24]=e("h3",{class:"text-lg font-bold text-gray-900"},"编辑分组",-1)),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors",onClick:B},u[23]||(u[23]=[e("i",{class:"fas fa-times"},null,-1)]))]),e("div",$s,[e("div",null,[u[25]||(u[25]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"分组名称 *",-1)),g(e("input",{"onUpdate:modelValue":u[6]||(u[6]=A=>S.value.name=A),type:"text",class:"form-input w-full",placeholder:"输入分组名称"},null,512),[[_,S.value.name]])]),e("div",null,[u[27]||(u[27]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"平台类型",-1)),e("div",Cs,[$(f(S.value.platform==="claude"?"Claude":"Gemini")+" ",1),u[26]||(u[26]=e("span",{class:"text-xs text-gray-500 ml-2"},"(不可修改)",-1))])]),e("div",null,[u[28]||(u[28]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-2"},"描述 (可选)",-1)),g(e("textarea",{"onUpdate:modelValue":u[7]||(u[7]=A=>S.value.description=A),rows:"2",class:"form-input w-full resize-none",placeholder:"分组描述..."},null,512),[[_,S.value.description]])]),e("div",Ts,[e("button",{class:"btn btn-primary px-4 py-2 flex-1",disabled:!S.value.name||m.value,onClick:L},[m.value?(a(),n("div",Us)):y("",!0),$(" "+f(m.value?"更新中...":"更新"),1)],8,As),e("button",{class:"btn btn-secondary px-4 py-2 flex-1",onClick:B}," 取消 ")])])])])):y("",!0)]))}},Vs={key:0,class:"fixed inset-0 modal z-50 flex items-center justify-center p-3 sm:p-4"},js={class:"modal-content w-full max-w-2xl p-4 sm:p-6 md:p-8 mx-auto max-h-[90vh] overflow-y-auto custom-scrollbar"},Ss={class:"flex items-center justify-between mb-4 sm:mb-6"},_s={class:"flex items-center gap-2 sm:gap-3"},Ms={class:"text-lg sm:text-xl font-bold text-gray-900"},Gs={key:0,class:"flex items-center justify-center mb-4 sm:mb-8"},Ks={class:"flex items-center space-x-2 sm:space-x-4"},Rs={class:"flex items-center"},Ls={class:"flex items-center"},Ps={key:1},Ds={class:"space-y-6"},zs={key:0},Es={class:"flex gap-4"},Os={class:"flex items-center cursor-pointer"},Ws={class:"flex items-center cursor-pointer"},qs={class:"flex items-center cursor-pointer"},Bs={key:1},Fs={class:"flex gap-4"},Ns={class:"flex items-center cursor-pointer"},Hs={class:"flex items-center cursor-pointer"},Js={key:0,class:"text-red-500 text-xs mt-1"},Ys={class:"flex gap-4"},Qs={class:"flex items-center cursor-pointer"},Xs={class:"flex items-center cursor-pointer"},Zs={class:"flex items-center cursor-pointer"},el={key:2},tl={class:"flex gap-2"},sl=["value"],ll={key:3},ol={key:4,class:"space-y-4"},al={key:0,class:"text-red-500 text-xs mt-1"},nl={key:0,class:"text-red-500 text-xs mt-1"},rl={class:"mb-2 flex gap-2"},il={key:5},ul={key:6,class:"space-y-4 bg-blue-50 p-4 rounded-lg border border-blue-200"},dl={class:"flex items-start gap-3 mb-4"},pl={key:0,class:"text-sm text-blue-800 mb-2"},ml={key:1,class:"text-sm text-blue-800 mb-2"},cl={class:"bg-white/80 rounded-lg p-3 mt-2 mb-2 border border-blue-300"},fl={key:0,class:"text-xs text-blue-800"},xl={key:1,class:"text-xs text-blue-800"},vl={key:0,class:"text-red-500 text-xs mt-1"},gl={class:"flex gap-3 pt-4"},yl=["disabled"],bl=["disabled"],wl={key:0,class:"loading-spinner mr-2"},kl={key:3,class:"space-y-6"},hl={class:"flex gap-4"},$l={class:"flex items-center cursor-pointer"},Cl={class:"flex items-center cursor-pointer"},Tl={class:"flex items-center cursor-pointer"},Al={key:0},Ul={class:"flex gap-2"},Il=["value"],Vl={key:1},jl={key:2},Sl={key:3,class:"space-y-4"},_l={class:"mb-2 flex gap-2"},Ml={key:4,class:"bg-amber-50 p-4 rounded-lg border border-amber-200"},Gl={class:"space-y-4"},Kl={class:"flex gap-3 pt-4"},Rl=["disabled"],Ll={key:0,class:"loading-spinner mr-2"},Ke={__name:"AccountForm",props:{account:{type:Object,default:null}},emits:["close","success"],setup(P,{emit:O}){var ue,de,ce,pe,fe,xe,ve,ge,ye,be,we,ke;const d=P,C=O,i=Pe(),{showConfirmModal:M,confirmOptions:I,showConfirm:T,handleConfirm:w,handleCancel:v}=Le(),m=ne(()=>!!d.account),G=b(!0),S=b(1),R=b(!1),q=()=>{var o;return(o=d.account)!=null&&o.proxy&&d.account.proxy.host&&d.account.proxy.port?{enabled:!0,type:d.account.proxy.type||"socks5",host:d.account.proxy.host,port:d.account.proxy.port,username:d.account.proxy.username||"",password:d.account.proxy.password||""}:{enabled:!1,type:"socks5",host:"",port:"",username:"",password:""}},l=b({platform:((ue=d.account)==null?void 0:ue.platform)||"claude",addType:"oauth",name:((de=d.account)==null?void 0:de.name)||"",description:((ce=d.account)==null?void 0:ce.description)||"",accountType:((pe=d.account)==null?void 0:pe.accountType)||"shared",groupId:"",projectId:((fe=d.account)==null?void 0:fe.projectId)||"",accessToken:"",refreshToken:"",proxy:q(),apiUrl:((xe=d.account)==null?void 0:xe.apiUrl)||"",apiKey:((ve=d.account)==null?void 0:ve.apiKey)||"",priority:((ge=d.account)==null?void 0:ge.priority)||50,supportedModels:((be=(ye=d.account)==null?void 0:ye.supportedModels)==null?void 0:be.join(`
`))||"",userAgent:((we=d.account)==null?void 0:we.userAgent)||"",rateLimitDuration:((ke=d.account)==null?void 0:ke.rateLimitDuration)||60}),x=b({name:"",accessToken:"",apiUrl:"",apiKey:""}),r=ne(()=>{var o;return((o=l.value.name)==null?void 0:o.trim())&&l.value.platform});ne(()=>{var o,t,s;return l.value.addType==="manual"?((o=l.value.name)==null?void 0:o.trim())&&((t=l.value.accessToken)==null?void 0:t.trim()):(s=l.value.name)==null?void 0:s.trim()});const L=async()=>{if(x.value.name="",!r.value){(!l.value.name||l.value.name.trim()==="")&&(x.value.name="请填写账户名称");return}if(l.value.accountType==="group"&&(!l.value.groupId||l.value.groupId.trim()==="")){h("请选择一个分组","error");return}l.value.platform==="gemini"&&S.value===1&&l.value.addType==="oauth"&&(!l.value.projectId||l.value.projectId.trim()==="")&&!await T("项目编号未填写",`您尚未填写项目编号。
如果您的Google账号绑定了Google Cloud或被识别为Workspace账号需要提供项目编号。
如果您使用的是普通个人账号,可以继续不填写。`,"继续","返回填写")||(S.value=2)},B=async o=>{R.value=!0;try{const t={name:l.value.name,description:l.value.description,accountType:l.value.accountType,groupId:l.value.accountType==="group"?l.value.groupId:void 0,proxy:l.value.proxy.enabled?{type:l.value.proxy.type,host:l.value.proxy.host,port:parseInt(l.value.proxy.port),username:l.value.proxy.username||null,password:l.value.proxy.password||null}:null};l.value.platform==="claude"?(t.claudeAiOauth=o.claudeAiOauth||o,t.priority=l.value.priority||50):l.value.platform==="gemini"&&(t.geminiOauth=o.tokens||o,l.value.projectId&&(t.projectId=l.value.projectId));let s;l.value.platform==="claude"?s=await i.createClaudeAccount(t):s=await i.createGeminiAccount(t),C("success",s)}catch(t){h(t.message||"账户创建失败","error")}finally{R.value=!1}},W=async()=>{x.value.name="",x.value.accessToken="",x.value.apiUrl="",x.value.apiKey="";let o=!1;if((!l.value.name||l.value.name.trim()==="")&&(x.value.name="请填写账户名称",o=!0),l.value.platform==="claude-console"?((!l.value.apiUrl||l.value.apiUrl.trim()==="")&&(x.value.apiUrl="请填写 API URL",o=!0),(!l.value.apiKey||l.value.apiKey.trim()==="")&&(x.value.apiKey="请填写 API Key",o=!0)):l.value.addType==="manual"&&(!l.value.accessToken||l.value.accessToken.trim()==="")&&(x.value.accessToken="请填写 Access Token",o=!0),l.value.accountType==="group"&&(!l.value.groupId||l.value.groupId.trim()==="")&&(h("请选择一个分组","error"),o=!0),!o){R.value=!0;try{const t={name:l.value.name,description:l.value.description,accountType:l.value.accountType,groupId:l.value.accountType==="group"?l.value.groupId:void 0,proxy:l.value.proxy.enabled?{type:l.value.proxy.type,host:l.value.proxy.host,port:parseInt(l.value.proxy.port),username:l.value.proxy.username||null,password:l.value.proxy.password||null}:null};if(l.value.platform==="claude"){const k=l.value.refreshToken?6e5:31536e6;t.claudeAiOauth={accessToken:l.value.accessToken,refreshToken:l.value.refreshToken||"",expiresAt:Date.now()+k,scopes:["user:inference"]},t.priority=l.value.priority||50}else if(l.value.platform==="gemini"){const k=l.value.refreshToken?6e5:31536e6;t.geminiOauth={access_token:l.value.accessToken,refresh_token:l.value.refreshToken||"",scope:"https://www.googleapis.com/auth/cloud-platform",token_type:"Bearer",expiry_date:Date.now()+k},l.value.projectId&&(t.projectId=l.value.projectId)}else l.value.platform==="claude-console"&&(t.apiUrl=l.value.apiUrl,t.apiKey=l.value.apiKey,t.priority=l.value.priority||50,t.supportedModels=l.value.supportedModels?l.value.supportedModels.split(`
`).filter(k=>k.trim()):[],t.userAgent=l.value.userAgent||null,t.rateLimitDuration=l.value.rateLimitDuration||60);let s;l.value.platform==="claude"?s=await i.createClaudeAccount(t):l.value.platform==="claude-console"?s=await i.createClaudeConsoleAccount(t):s=await i.createGeminiAccount(t),C("success",s)}catch(t){h(t.message||"账户创建失败","error")}finally{R.value=!1}}},j=async()=>{if(x.value.name="",!l.value.name||l.value.name.trim()===""){x.value.name="请填写账户名称";return}if(l.value.accountType==="group"&&(!l.value.groupId||l.value.groupId.trim()==="")){h("请选择一个分组","error");return}if(!(l.value.platform==="gemini"&&(!l.value.projectId||l.value.projectId.trim()==="")&&!await T("项目编号未填写",`您尚未填写项目编号。
如果您的Google账号绑定了Google Cloud或被识别为Workspace账号需要提供项目编号。
如果您使用的是普通个人账号,可以继续不填写。`,"继续保存","返回填写"))){R.value=!0;try{const o={name:l.value.name,description:l.value.description,accountType:l.value.accountType,groupId:l.value.accountType==="group"?l.value.groupId:void 0,proxy:l.value.proxy.enabled?{type:l.value.proxy.type,host:l.value.proxy.host,port:parseInt(l.value.proxy.port),username:l.value.proxy.username||null,password:l.value.proxy.password||null}:null};if(l.value.accessToken||l.value.refreshToken){if(d.account.platform==="claude"){const t=l.value.refreshToken?6e5:31536e6;o.claudeAiOauth={accessToken:l.value.accessToken||"",refreshToken:l.value.refreshToken||"",expiresAt:Date.now()+t,scopes:["user:inference"]}}else if(d.account.platform==="gemini"){const t=l.value.refreshToken?6e5:31536e6;o.geminiOauth={access_token:l.value.accessToken||"",refresh_token:l.value.refreshToken||"",scope:"https://www.googleapis.com/auth/cloud-platform",token_type:"Bearer",expiry_date:Date.now()+t}}}d.account.platform==="gemini"&&l.value.projectId&&(o.projectId=l.value.projectId),d.account.platform==="claude"&&(o.priority=l.value.priority||50),d.account.platform==="claude-console"&&(o.apiUrl=l.value.apiUrl,l.value.apiKey&&(o.apiKey=l.value.apiKey),o.priority=l.value.priority||50,o.supportedModels=l.value.supportedModels?l.value.supportedModels.split(`
`).filter(t=>t.trim()):[],o.userAgent=l.value.userAgent||null,o.rateLimitDuration=l.value.rateLimitDuration||60),d.account.platform==="claude"?await i.updateClaudeAccount(d.account.id,o):d.account.platform==="claude-console"?await i.updateClaudeConsoleAccount(d.account.id,o):await i.updateGeminiAccount(d.account.id,o),C("success")}catch(o){h(o.message||"账户更新失败","error")}finally{R.value=!1}}};E(()=>l.value.name,()=>{var o;x.value.name&&((o=l.value.name)!=null&&o.trim())&&(x.value.name="")}),E(()=>l.value.accessToken,()=>{var o;x.value.accessToken&&((o=l.value.accessToken)!=null&&o.trim())&&(x.value.accessToken="")}),E(()=>l.value.apiUrl,()=>{var o;x.value.apiUrl&&((o=l.value.apiUrl)!=null&&o.trim())&&(x.value.apiUrl="")}),E(()=>l.value.apiKey,()=>{var o;x.value.apiKey&&((o=l.value.apiKey)!=null&&o.trim())&&(x.value.apiKey="")});const u=b([]),A=b(!1),Z=b(!1),oe=ne(()=>{const o=l.value.platform==="claude-console"?"claude":l.value.platform;return u.value.filter(t=>t.platform===o)}),c=async()=>{A.value=!0;try{const o=await V.get("/admin/account-groups");u.value=o.data||[]}catch{h("加载分组列表失败","error"),u.value=[]}finally{A.value=!1}},p=async()=>{await c(),h("分组列表已刷新","success")},U=async()=>{await c()};E(()=>l.value.platform,o=>{o==="claude-console"&&(l.value.addType="manual"),l.value.accountType==="group"&&(l.value.groupId="")}),E(()=>l.value.accountType,o=>{o==="group"&&u.value.length===0&&c()}),E(()=>l.value.groupId,o=>{o==="__new__"&&(l.value.groupId="",Z.value=!0)});const F=o=>{const t=l.value.supportedModels?l.value.supportedModels.split(`
`).filter(s=>s.trim()):[];if(t.includes(o)){h(`模型 ${o} 已存在`,"info");return}t.push(o),l.value.supportedModels=t.join(`
`),h(`已添加模型 ${o}`,"success")};return E(()=>d.account,o=>{var t;if(o){const s=o.proxy&&o.proxy.host&&o.proxy.port?{enabled:!0,type:o.proxy.type||"socks5",host:o.proxy.host,port:o.proxy.port,username:o.proxy.username||"",password:o.proxy.password||""}:{enabled:!1,type:"socks5",host:"",port:"",username:"",password:""};l.value={platform:o.platform,addType:"oauth",name:o.name,description:o.description||"",accountType:o.accountType||"shared",groupId:"",projectId:o.projectId||"",accessToken:"",refreshToken:"",proxy:s,apiUrl:o.apiUrl||"",apiKey:"",priority:o.priority||50,supportedModels:((t=o.supportedModels)==null?void 0:t.join(`
`))||"",userAgent:o.userAgent||"",rateLimitDuration:o.rateLimitDuration||60},o.accountType==="group"&&c().then(()=>{u.value.forEach(k=>{V.get(`/admin/account-groups/${k.id}/members`).then(D=>{(D.data||[]).some(H=>H.id===o.id)&&(l.value.groupId=k.id)}).catch(()=>{})})})}},{immediate:!0}),(o,t)=>(a(),le(Ae,{to:"body"},[G.value?(a(),n("div",Vs,[e("div",js,[e("div",Ss,[e("div",_s,[t[48]||(t[48]=e("div",{class:"w-8 h-8 sm:w-10 sm:h-10 bg-gradient-to-br from-green-500 to-green-600 rounded-lg sm:rounded-xl flex items-center justify-center"},[e("i",{class:"fas fa-user-circle text-white text-sm sm:text-base"})],-1)),e("h3",Ms,f(m.value?"编辑账户":"添加账户"),1)]),e("button",{class:"text-gray-400 hover:text-gray-600 transition-colors p-1",onClick:t[0]||(t[0]=s=>o.$emit("close"))},t[49]||(t[49]=[e("i",{class:"fas fa-times text-lg sm:text-xl"},null,-1)]))]),!m.value&&l.value.addType==="oauth"?(a(),n("div",Gs,[e("div",Ks,[e("div",Rs,[e("div",{class:K(["w-6 h-6 sm:w-8 sm:h-8 rounded-full flex items-center justify-center text-xs sm:text-sm font-semibold",S.value>=1?"bg-blue-500 text-white":"bg-gray-200 text-gray-500"])}," 1 ",2),t[50]||(t[50]=e("span",{class:"ml-1.5 sm:ml-2 text-xs sm:text-sm font-medium text-gray-700"},"基本信息",-1))]),t[52]||(t[52]=e("div",{class:"w-4 sm:w-8 h-0.5 bg-gray-300"},null,-1)),e("div",Ls,[e("div",{class:K(["w-6 h-6 sm:w-8 sm:h-8 rounded-full flex items-center justify-center text-xs sm:text-sm font-semibold",S.value>=2?"bg-blue-500 text-white":"bg-gray-200 text-gray-500"])}," 2 ",2),t[51]||(t[51]=e("span",{class:"ml-1.5 sm:ml-2 text-xs sm:text-sm font-medium text-gray-700"},"授权认证",-1))])])])):y("",!0),S.value===1&&!m.value?(a(),n("div",Ps,[e("div",Ds,[m.value?y("",!0):(a(),n("div",zs,[t[56]||(t[56]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"平台",-1)),e("div",Es,[e("label",Os,[g(e("input",{"onUpdate:modelValue":t[1]||(t[1]=s=>l.value.platform=s),type:"radio",value:"claude",class:"mr-2"},null,512),[[X,l.value.platform]]),t[53]||(t[53]=e("span",{class:"text-sm text-gray-700"},"Claude",-1))]),e("label",Ws,[g(e("input",{"onUpdate:modelValue":t[2]||(t[2]=s=>l.value.platform=s),type:"radio",value:"claude-console",class:"mr-2"},null,512),[[X,l.value.platform]]),t[54]||(t[54]=e("span",{class:"text-sm text-gray-700"},"Claude Console",-1))]),e("label",qs,[g(e("input",{"onUpdate:modelValue":t[3]||(t[3]=s=>l.value.platform=s),type:"radio",value:"gemini",class:"mr-2"},null,512),[[X,l.value.platform]]),t[55]||(t[55]=e("span",{class:"text-sm text-gray-700"},"Gemini",-1))])])])),!m.value&&l.value.platform!=="claude-console"?(a(),n("div",Bs,[t[59]||(t[59]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"添加方式",-1)),e("div",Fs,[e("label",Ns,[g(e("input",{"onUpdate:modelValue":t[4]||(t[4]=s=>l.value.addType=s),type:"radio",value:"oauth",class:"mr-2"},null,512),[[X,l.value.addType]]),t[57]||(t[57]=e("span",{class:"text-sm text-gray-700"},"OAuth 授权 (推荐)",-1))]),e("label",Hs,[g(e("input",{"onUpdate:modelValue":t[5]||(t[5]=s=>l.value.addType=s),type:"radio",value:"manual",class:"mr-2"},null,512),[[X,l.value.addType]]),t[58]||(t[58]=e("span",{class:"text-sm text-gray-700"},"手动输入 Access Token",-1))])])])):y("",!0),e("div",null,[t[60]||(t[60]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"账户名称",-1)),g(e("input",{"onUpdate:modelValue":t[6]||(t[6]=s=>l.value.name=s),type:"text",required:"",class:K(["form-input w-full",{"border-red-500":x.value.name}]),placeholder:"为账户设置一个易识别的名称"},null,2),[[_,l.value.name]]),x.value.name?(a(),n("p",Js,f(x.value.name),1)):y("",!0)]),e("div",null,[t[61]||(t[61]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"描述 (可选)",-1)),g(e("textarea",{"onUpdate:modelValue":t[7]||(t[7]=s=>l.value.description=s),rows:"3",class:"form-input w-full resize-none",placeholder:"账户用途说明..."},null,512),[[_,l.value.description]])]),e("div",null,[t[65]||(t[65]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"账户类型",-1)),e("div",Ys,[e("label",Qs,[g(e("input",{"onUpdate:modelValue":t[8]||(t[8]=s=>l.value.accountType=s),type:"radio",value:"shared",class:"mr-2"},null,512),[[X,l.value.accountType]]),t[62]||(t[62]=e("span",{class:"text-sm text-gray-700"},"共享账户",-1))]),e("label",Xs,[g(e("input",{"onUpdate:modelValue":t[9]||(t[9]=s=>l.value.accountType=s),type:"radio",value:"dedicated",class:"mr-2"},null,512),[[X,l.value.accountType]]),t[63]||(t[63]=e("span",{class:"text-sm text-gray-700"},"专属账户",-1))]),e("label",Zs,[g(e("input",{"onUpdate:modelValue":t[10]||(t[10]=s=>l.value.accountType=s),type:"radio",value:"group",class:"mr-2"},null,512),[[X,l.value.accountType]]),t[64]||(t[64]=e("span",{class:"text-sm text-gray-700"},"分组调度",-1))])]),t[66]||(t[66]=e("p",{class:"text-xs text-gray-500 mt-2"}," 共享账户供所有API Key使用专属账户仅供特定API Key使用分组调度加入分组供分组内调度 ",-1))]),l.value.accountType==="group"?(a(),n("div",el,[t[69]||(t[69]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"选择分组 *",-1)),e("div",tl,[g(e("select",{"onUpdate:modelValue":t[11]||(t[11]=s=>l.value.groupId=s),class:"form-input flex-1",required:""},[t[67]||(t[67]=e("option",{value:""},"请选择分组",-1)),(a(!0),n(re,null,ie(oe.value,s=>(a(),n("option",{key:s.id,value:s.id},f(s.name)+" ("+f(s.memberCount||0)+" 个成员) ",9,sl))),128)),t[68]||(t[68]=e("option",{value:"__new__"},"+ 新建分组",-1))],512),[[me,l.value.groupId]]),e("button",{type:"button",class:"px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",onClick:p},[e("i",{class:K(["fas fa-sync-alt",{"animate-spin":A.value}])},null,2)])])])):y("",!0),l.value.platform==="gemini"?(a(),n("div",ll,[t[70]||(t[70]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"项目编号 (可选)",-1)),g(e("input",{"onUpdate:modelValue":t[12]||(t[12]=s=>l.value.projectId=s),type:"text",class:"form-input w-full",placeholder:"例如123456789012纯数字"},null,512),[[_,l.value.projectId]]),t[71]||(t[71]=e("div",{class:"mt-2 p-3 bg-yellow-50 border border-yellow-200 rounded-lg"},[e("div",{class:"flex items-start gap-2"},[e("i",{class:"fas fa-info-circle text-yellow-600 mt-0.5"}),e("div",{class:"text-xs text-yellow-700"},[e("p",{class:"font-medium mb-1"}," Google Cloud/Workspace 账号需要提供项目编号 "),e("p",null,"某些 Google 账号(特别是绑定了 Google Cloud 的账号)会被识别为 Workspace 账号,需要提供额外的项目编号。"),e("div",{class:"mt-2 p-2 bg-white rounded border border-yellow-300"},[e("p",{class:"font-medium mb-1"}," 如何获取项目编号: "),e("ol",{class:"list-decimal list-inside space-y-1 ml-2"},[e("li",null,[$(" 访问 "),e("a",{href:"https://console.cloud.google.com/welcome",target:"_blank",class:"text-blue-600 hover:underline font-medium"},"Google Cloud Console")]),e("li",null,[$("复制"),e("span",{class:"font-semibold text-red-600"},"项目编号Project Number"),$("通常是12位纯数字")]),e("li",{class:"text-red-600"}," ⚠️ 注意不要复制项目IDProject ID要复制项目编号 ")])]),e("p",{class:"mt-2"},[e("strong",null,"提示:"),$("如果您的账号是普通个人账号(未绑定 Google Cloud请留空此字段。 ")])])])],-1))])):y("",!0),l.value.platform==="claude-console"&&!m.value?(a(),n("div",ol,[e("div",null,[t[72]||(t[72]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"API URL *",-1)),g(e("input",{"onUpdate:modelValue":t[13]||(t[13]=s=>l.value.apiUrl=s),type:"text",required:"",class:K(["form-input w-full",{"border-red-500":x.value.apiUrl}]),placeholder:"例如https://api.example.com"},null,2),[[_,l.value.apiUrl]]),x.value.apiUrl?(a(),n("p",al,f(x.value.apiUrl),1)):y("",!0)]),e("div",null,[t[73]||(t[73]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"API Key *",-1)),g(e("input",{"onUpdate:modelValue":t[14]||(t[14]=s=>l.value.apiKey=s),type:"password",required:"",class:K(["form-input w-full",{"border-red-500":x.value.apiKey}]),placeholder:"请输入API Key"},null,2),[[_,l.value.apiKey]]),x.value.apiKey?(a(),n("p",nl,f(x.value.apiKey),1)):y("",!0)]),e("div",null,[t[74]||(t[74]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"支持的模型 (可选)--注意,ClaudeCode必须加上hiku模型",-1)),e("div",rl,[e("button",{type:"button",class:"px-3 py-1 text-xs bg-blue-100 text-blue-700 rounded-lg hover:bg-blue-200 transition-colors",onClick:t[15]||(t[15]=s=>F("claude-sonnet-4-20250514"))}," + claude-sonnet-4-20250514 "),e("button",{type:"button",class:"px-3 py-1 text-xs bg-purple-100 text-purple-700 rounded-lg hover:bg-purple-200 transition-colors",onClick:t[16]||(t[16]=s=>F("claude-opus-4-20250514"))}," + claude-opus-4-20250514 "),e("button",{type:"button",class:"px-3 py-1 text-xs bg-green-100 text-green-700 rounded-lg hover:bg-purple-200 transition-colors",onClick:t[17]||(t[17]=s=>F("claude-3-5-haiku-20241022"))}," + claude-3-5-haiku-20241022 ")]),g(e("textarea",{"onUpdate:modelValue":t[18]||(t[18]=s=>l.value.supportedModels=s),rows:"3",class:"form-input w-full resize-none",placeholder:"每行一个模型,留空表示支持所有模型。特别注意,ClaudeCode必须加上hiku模型"},null,512),[[_,l.value.supportedModels]]),t[75]||(t[75]=e("p",{class:"text-xs text-gray-500 mt-1"}," 留空表示支持所有模型。如果指定模型,请求中的模型不在列表内将不会调度到此账号 ",-1))]),e("div",null,[t[76]||(t[76]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"自定义 User-Agent (可选)",-1)),g(e("input",{"onUpdate:modelValue":t[19]||(t[19]=s=>l.value.userAgent=s),type:"text",class:"form-input w-full",placeholder:"默认claude-cli/1.0.61 (console, cli)"},null,512),[[_,l.value.userAgent]])]),e("div",null,[t[77]||(t[77]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"限流时间 (分钟)",-1)),g(e("input",{"onUpdate:modelValue":t[20]||(t[20]=s=>l.value.rateLimitDuration=s),type:"number",min:"1",class:"form-input w-full",placeholder:"默认60分钟"},null,512),[[_,l.value.rateLimitDuration,void 0,{number:!0}]]),t[78]||(t[78]=e("p",{class:"text-xs text-gray-500 mt-1"}," 当账号返回429错误时暂停调度的时间分钟 ",-1))])])):y("",!0),l.value.platform==="claude"||l.value.platform==="claude-console"?(a(),n("div",il,[t[79]||(t[79]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"调度优先级 (1-100)",-1)),g(e("input",{"onUpdate:modelValue":t[21]||(t[21]=s=>l.value.priority=s),type:"number",min:"1",max:"100",class:"form-input w-full",placeholder:"数字越小优先级越高默认50"},null,512),[[_,l.value.priority,void 0,{number:!0}]]),t[80]||(t[80]=e("p",{class:"text-xs text-gray-500 mt-1"}," 数字越小优先级越高建议范围1-100 ",-1))])):y("",!0),l.value.addType==="manual"&&l.value.platform!=="claude-console"?(a(),n("div",ul,[e("div",dl,[t[86]||(t[86]=e("div",{class:"w-8 h-8 bg-blue-500 rounded-lg flex items-center justify-center flex-shrink-0 mt-1"},[e("i",{class:"fas fa-info text-white text-sm"})],-1)),e("div",null,[t[84]||(t[84]=e("h5",{class:"font-semibold text-blue-900 mb-2"}," 手动输入 Token ",-1)),l.value.platform==="claude"?(a(),n("p",pl," 请输入有效的 Claude Access Token。如果您有 Refresh Token建议也一并填写以支持自动刷新。 ")):l.value.platform==="gemini"?(a(),n("p",ml," 请输入有效的 Gemini Access Token。如果您有 Refresh Token建议也一并填写以支持自动刷新。 ")):y("",!0),e("div",cl,[t[83]||(t[83]=e("p",{class:"text-sm text-blue-900 font-medium mb-1"},[e("i",{class:"fas fa-folder-open mr-1"}),$(" 获取 Access Token 的方法: ")],-1)),l.value.platform==="claude"?(a(),n("p",fl,t[81]||(t[81]=[$(" 请从已登录 Claude Code 的机器上获取 ",-1),e("code",{class:"bg-blue-100 px-1 py-0.5 rounded font-mono"},"~/.claude/.credentials.json",-1),$(" 文件中的凭证, 请勿使用 Claude 官网 API Keys 页面的密钥。 ",-1)]))):l.value.platform==="gemini"?(a(),n("p",xl,t[82]||(t[82]=[$(" 请从已登录 Gemini CLI 的机器上获取 ",-1),e("code",{class:"bg-blue-100 px-1 py-0.5 rounded font-mono"},"~/.config/gemini/credentials.json",-1),$(" 文件中的凭证。 ",-1)]))):y("",!0)]),t[85]||(t[85]=e("p",{class:"text-xs text-blue-600"}," 💡 如果未填写 Refresh TokenToken 过期后需要手动更新。 ",-1))])]),e("div",null,[t[87]||(t[87]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"Access Token *",-1)),g(e("textarea",{"onUpdate:modelValue":t[22]||(t[22]=s=>l.value.accessToken=s),rows:"4",required:"",class:K(["form-input w-full resize-none font-mono text-xs",{"border-red-500":x.value.accessToken}]),placeholder:"请输入 Access Token..."},null,2),[[_,l.value.accessToken]]),x.value.accessToken?(a(),n("p",vl,f(x.value.accessToken),1)):y("",!0)]),e("div",null,[t[88]||(t[88]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"Refresh Token (可选)",-1)),g(e("textarea",{"onUpdate:modelValue":t[23]||(t[23]=s=>l.value.refreshToken=s),rows:"4",class:"form-input w-full resize-none font-mono text-xs",placeholder:"请输入 Refresh Token..."},null,512),[[_,l.value.refreshToken]])])])):y("",!0),$e(Ge,{modelValue:l.value.proxy,"onUpdate:modelValue":t[24]||(t[24]=s=>l.value.proxy=s)},null,8,["modelValue"]),e("div",gl,[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:t[25]||(t[25]=s=>o.$emit("close"))}," 取消 "),l.value.addType==="oauth"&&l.value.platform!=="claude-console"?(a(),n("button",{key:0,type:"button",disabled:R.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold",onClick:L}," 下一步 ",8,yl)):(a(),n("button",{key:1,type:"button",disabled:R.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold",onClick:W},[R.value?(a(),n("div",wl)):y("",!0),$(" "+f(R.value?"创建中...":"创建"),1)],8,bl))])])])):y("",!0),S.value===2&&l.value.addType==="oauth"?(a(),le(Et,{key:2,platform:l.value.platform,proxy:l.value.proxy,onSuccess:B,onBack:t[26]||(t[26]=s=>S.value=1)},null,8,["platform","proxy"])):y("",!0),m.value?(a(),n("div",kl,[e("div",null,[t[89]||(t[89]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"账户名称",-1)),g(e("input",{"onUpdate:modelValue":t[27]||(t[27]=s=>l.value.name=s),type:"text",required:"",class:"form-input w-full",placeholder:"为账户设置一个易识别的名称"},null,512),[[_,l.value.name]])]),e("div",null,[t[90]||(t[90]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"描述 (可选)",-1)),g(e("textarea",{"onUpdate:modelValue":t[28]||(t[28]=s=>l.value.description=s),rows:"3",class:"form-input w-full resize-none",placeholder:"账户用途说明..."},null,512),[[_,l.value.description]])]),e("div",null,[t[94]||(t[94]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"账户类型",-1)),e("div",hl,[e("label",$l,[g(e("input",{"onUpdate:modelValue":t[29]||(t[29]=s=>l.value.accountType=s),type:"radio",value:"shared",class:"mr-2"},null,512),[[X,l.value.accountType]]),t[91]||(t[91]=e("span",{class:"text-sm text-gray-700"},"共享账户",-1))]),e("label",Cl,[g(e("input",{"onUpdate:modelValue":t[30]||(t[30]=s=>l.value.accountType=s),type:"radio",value:"dedicated",class:"mr-2"},null,512),[[X,l.value.accountType]]),t[92]||(t[92]=e("span",{class:"text-sm text-gray-700"},"专属账户",-1))]),e("label",Tl,[g(e("input",{"onUpdate:modelValue":t[31]||(t[31]=s=>l.value.accountType=s),type:"radio",value:"group",class:"mr-2"},null,512),[[X,l.value.accountType]]),t[93]||(t[93]=e("span",{class:"text-sm text-gray-700"},"分组调度",-1))])]),t[95]||(t[95]=e("p",{class:"text-xs text-gray-500 mt-2"}," 共享账户供所有API Key使用专属账户仅供特定API Key使用分组调度加入分组供分组内调度 ",-1))]),l.value.accountType==="group"?(a(),n("div",Al,[t[98]||(t[98]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"选择分组 *",-1)),e("div",Ul,[g(e("select",{"onUpdate:modelValue":t[32]||(t[32]=s=>l.value.groupId=s),class:"form-input flex-1",required:""},[t[96]||(t[96]=e("option",{value:""},"请选择分组",-1)),(a(!0),n(re,null,ie(oe.value,s=>(a(),n("option",{key:s.id,value:s.id},f(s.name)+" ("+f(s.memberCount||0)+" 个成员) ",9,Il))),128)),t[97]||(t[97]=e("option",{value:"__new__"},"+ 新建分组",-1))],512),[[me,l.value.groupId]]),e("button",{type:"button",class:"px-3 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",onClick:p},[e("i",{class:K(["fas fa-sync-alt",{"animate-spin":A.value}])},null,2)])])])):y("",!0),l.value.platform==="gemini"?(a(),n("div",Vl,[t[99]||(t[99]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"项目编号 (可选)",-1)),g(e("input",{"onUpdate:modelValue":t[33]||(t[33]=s=>l.value.projectId=s),type:"text",class:"form-input w-full",placeholder:"例如123456789012纯数字"},null,512),[[_,l.value.projectId]]),t[100]||(t[100]=e("p",{class:"text-xs text-gray-500 mt-2"}," Google Cloud/Workspace 账号可能需要提供项目编号 ",-1))])):y("",!0),l.value.platform==="claude"||l.value.platform==="claude-console"?(a(),n("div",jl,[t[101]||(t[101]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"调度优先级 (1-100)",-1)),g(e("input",{"onUpdate:modelValue":t[34]||(t[34]=s=>l.value.priority=s),type:"number",min:"1",max:"100",class:"form-input w-full",placeholder:"数字越小优先级越高"},null,512),[[_,l.value.priority,void 0,{number:!0}]]),t[102]||(t[102]=e("p",{class:"text-xs text-gray-500 mt-1"}," 数字越小优先级越高建议范围1-100 ",-1))])):y("",!0),l.value.platform==="claude-console"?(a(),n("div",Sl,[e("div",null,[t[103]||(t[103]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"API URL",-1)),g(e("input",{"onUpdate:modelValue":t[35]||(t[35]=s=>l.value.apiUrl=s),type:"text",required:"",class:"form-input w-full",placeholder:"例如https://api.example.com"},null,512),[[_,l.value.apiUrl]])]),e("div",null,[t[104]||(t[104]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"API Key",-1)),g(e("input",{"onUpdate:modelValue":t[36]||(t[36]=s=>l.value.apiKey=s),type:"password",class:"form-input w-full",placeholder:"留空表示不更新"},null,512),[[_,l.value.apiKey]]),t[105]||(t[105]=e("p",{class:"text-xs text-gray-500 mt-1"}," 留空表示不更新 API Key ",-1))]),e("div",null,[t[106]||(t[106]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"支持的模型 (可选)",-1)),e("div",_l,[e("button",{type:"button",class:"px-3 py-1 text-xs bg-blue-100 text-blue-700 rounded-lg hover:bg-blue-200 transition-colors",onClick:t[37]||(t[37]=s=>F("claude-sonnet-4-20250514"))}," + claude-sonnet-4-20250514 "),e("button",{type:"button",class:"px-3 py-1 text-xs bg-purple-100 text-purple-700 rounded-lg hover:bg-purple-200 transition-colors",onClick:t[38]||(t[38]=s=>F("claude-opus-4-20250514"))}," + claude-opus-4-20250514 "),e("button",{type:"button",class:"px-3 py-1 text-xs bg-green-100 text-green-700 rounded-lg hover:bg-purple-200 transition-colors",onClick:t[39]||(t[39]=s=>F("claude-3-5-haiku-20241022"))}," + claude-3-5-haiku-20241022 ")]),g(e("textarea",{"onUpdate:modelValue":t[40]||(t[40]=s=>l.value.supportedModels=s),rows:"3",class:"form-input w-full resize-none",placeholder:"每行一个模型,留空表示支持所有模型。特别注意,ClaudeCode必须加上hiku模型"},null,512),[[_,l.value.supportedModels]])]),e("div",null,[t[107]||(t[107]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"自定义 User-Agent (可选)",-1)),g(e("input",{"onUpdate:modelValue":t[41]||(t[41]=s=>l.value.userAgent=s),type:"text",class:"form-input w-full",placeholder:"默认claude-cli/1.0.61 (console, cli)"},null,512),[[_,l.value.userAgent]])]),e("div",null,[t[108]||(t[108]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"限流时间 (分钟)",-1)),g(e("input",{"onUpdate:modelValue":t[42]||(t[42]=s=>l.value.rateLimitDuration=s),type:"number",min:"1",class:"form-input w-full"},null,512),[[_,l.value.rateLimitDuration,void 0,{number:!0}]])])])):y("",!0),l.value.platform!=="claude-console"?(a(),n("div",Ml,[t[111]||(t[111]=e("div",{class:"flex items-start gap-3 mb-4"},[e("div",{class:"w-8 h-8 bg-amber-500 rounded-lg flex items-center justify-center flex-shrink-0 mt-1"},[e("i",{class:"fas fa-key text-white text-sm"})]),e("div",null,[e("h5",{class:"font-semibold text-amber-900 mb-2"}," 更新 Token "),e("p",{class:"text-sm text-amber-800 mb-2"}," 可以更新 Access Token 和 Refresh Token。为了安全起见不会显示当前的 Token 值。 "),e("p",{class:"text-xs text-amber-600"}," 💡 留空表示不更新该字段。 ")])],-1)),e("div",Gl,[e("div",null,[t[109]||(t[109]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"新的 Access Token",-1)),g(e("textarea",{"onUpdate:modelValue":t[43]||(t[43]=s=>l.value.accessToken=s),rows:"4",class:"form-input w-full resize-none font-mono text-xs",placeholder:"留空表示不更新..."},null,512),[[_,l.value.accessToken]])]),e("div",null,[t[110]||(t[110]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"新的 Refresh Token",-1)),g(e("textarea",{"onUpdate:modelValue":t[44]||(t[44]=s=>l.value.refreshToken=s),rows:"4",class:"form-input w-full resize-none font-mono text-xs",placeholder:"留空表示不更新..."},null,512),[[_,l.value.refreshToken]])])])])):y("",!0),$e(Ge,{modelValue:l.value.proxy,"onUpdate:modelValue":t[45]||(t[45]=s=>l.value.proxy=s)},null,8,["modelValue"]),e("div",Kl,[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:t[46]||(t[46]=s=>o.$emit("close"))}," 取消 "),e("button",{type:"button",disabled:R.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold",onClick:j},[R.value?(a(),n("div",Ll)):y("",!0),$(" "+f(R.value?"更新中...":"更新"),1)],8,Rl)])])):y("",!0)])])):y("",!0),$e(De,{show:Y(M),title:Y(I).title,message:Y(I).message,"confirm-text":Y(I).confirmText,"cancel-text":Y(I).cancelText,onConfirm:Y(w),onCancel:Y(v)},null,8,["show","title","message","confirm-text","cancel-text","onConfirm","onCancel"]),Z.value?(a(),le(Is,{key:1,onClose:t[47]||(t[47]=s=>Z.value=!1),onRefresh:U})):y("",!0)]))}},Pl={class:"accounts-container"},Dl={class:"card p-4 sm:p-6"},zl={class:"flex flex-col gap-4 mb-4 sm:mb-6"},El={class:"flex flex-col sm:flex-row gap-2 sm:items-center sm:justify-between"},Ol={class:"flex flex-col sm:flex-row gap-2"},Wl=["value"],ql={key:0,class:"text-center py-12"},Bl={key:1,class:"text-center py-12"},Fl={key:2,class:"hidden md:block table-container"},Nl={class:"w-full table-fixed"},Hl={class:"bg-gray-50/80 backdrop-blur-sm"},Jl={key:1,class:"fas fa-sort ml-1 text-gray-400"},Yl={key:1,class:"fas fa-sort ml-1 text-gray-400"},Ql={key:1,class:"fas fa-sort ml-1 text-gray-400"},Xl={key:1,class:"fas fa-sort ml-1 text-gray-400"},Zl={class:"divide-y divide-gray-200/50"},eo={class:"px-3 py-4"},to={class:"flex items-center"},so={class:"min-w-0"},lo={class:"flex items-center gap-2"},oo=["title"],ao={key:0,class:"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800"},no={key:1,class:"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800"},ro={key:2,class:"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800"},io=["title"],uo=["title"],po={class:"px-3 py-4"},mo={class:"flex items-center gap-1"},co={key:0,class:"flex items-center gap-1.5 px-2.5 py-1 bg-gradient-to-r from-yellow-100 to-amber-100 rounded-lg border border-yellow-200"},fo={class:"text-xs font-medium text-yellow-700"},xo={key:1,class:"flex items-center gap-1.5 px-2.5 py-1 bg-gradient-to-r from-purple-100 to-pink-100 rounded-lg border border-purple-200"},vo={key:2,class:"flex items-center gap-1.5 px-2.5 py-1 bg-gradient-to-r from-indigo-100 to-blue-100 rounded-lg border border-indigo-200"},go={class:"text-xs font-medium text-indigo-700"},yo={class:"px-3 py-4 whitespace-nowrap"},bo={class:"flex flex-col gap-1"},wo={key:0,class:"inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-800"},ko={key:1,class:"inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-gray-100 text-gray-700"},ho=["title"],$o={key:3,class:"text-xs text-gray-500"},Co={class:"px-3 py-4 whitespace-nowrap"},To={key:0,class:"flex items-center gap-2"},Ao={class:"w-16 bg-gray-200 rounded-full h-2"},Uo={class:"text-xs text-gray-700 font-medium min-w-[20px]"},Io={key:1,class:"text-gray-400 text-sm"},Vo={class:"px-3 py-4 text-sm text-gray-600"},jo=["title"],So={key:1,class:"text-gray-400"},_o={class:"px-3 py-4 whitespace-nowrap text-sm"},Mo={key:0,class:"space-y-1"},Go={class:"flex items-center gap-2"},Ko={class:"text-sm font-medium text-gray-900"},Ro={class:"flex items-center gap-2"},Lo={class:"text-xs text-gray-600"},Po={key:0,class:"text-xs text-gray-500"},Do={key:1,class:"text-gray-400 text-xs"},zo={class:"px-3 py-4 whitespace-nowrap"},Eo={key:0,class:"space-y-2"},Oo={class:"flex items-center gap-2"},Wo={class:"w-24 bg-gray-200 rounded-full h-2"},qo={class:"text-xs text-gray-700 font-medium min-w-[32px]"},Bo={class:"text-xs text-gray-600"},Fo={key:0,class:"text-indigo-600 font-medium"},No={key:1,class:"text-gray-400 text-sm"},Ho={key:2,class:"text-gray-400 text-sm"},Jo={class:"px-3 py-4 whitespace-nowrap text-sm text-gray-600"},Yo={class:"px-3 py-4 whitespace-nowrap text-sm font-medium"},Qo={class:"flex items-center gap-1 flex-wrap"},Xo=["disabled","title","onClick"],Zo=["disabled","title","onClick"],ea={class:"ml-1"},ta=["onClick"],sa=["onClick"],la={key:3,class:"md:hidden space-y-3"},oa={class:"flex items-start justify-between mb-3"},aa={class:"flex items-center gap-3"},na={class:"text-sm font-semibold text-gray-900"},ra={class:"flex items-center gap-2 mt-0.5"},ia={class:"text-xs text-gray-500"},ua={class:"text-xs text-gray-500"},da={class:"grid grid-cols-2 gap-3 mb-3"},pa={class:"text-sm font-semibold text-gray-900"},ma={class:"text-xs text-gray-500 mt-0.5"},ca={class:"text-sm font-semibold text-gray-900"},fa={class:"text-xs text-gray-500 mt-0.5"},xa={class:"space-y-2 mb-3"},va={key:0,class:"flex items-center justify-between text-xs"},ga={class:"flex items-center gap-2"},ya={class:"w-20 h-1.5 bg-gray-200 rounded-full overflow-hidden"},ba={class:"flex items-center justify-between text-xs"},wa={class:"text-gray-700"},ka={key:1,class:"flex items-center justify-between text-xs"},ha={class:"text-gray-700"},$a={class:"flex items-center justify-between text-xs"},Ca={class:"text-gray-700 font-medium"},Ta={class:"flex gap-2 mt-3 pt-3 border-t border-gray-100"},Aa=["disabled","onClick"],Ua=["onClick","disabled"],Ia=["onClick"],Va=["onClick"],ja={__name:"AccountsView",setup(P){const{showConfirmModal:O,confirmOptions:d,showConfirm:C,handleConfirm:i,handleCancel:M}=Le(),I=b([]),T=b(!1),w=b("name"),v=b(""),m=b("asc"),G=b([]),S=b({}),R=b([]),q=b("all"),l=b([]),x=b(!1),r=b(!1),L=b(null),B=ne(()=>{const o=l.value.length>0?l.value:I.value;return v.value?[...o].sort((s,k)=>{var H,Q,J,z,ee,te,ae,Ue,Ie,Ve,je,Se;let D=s[v.value],N=k[v.value];return v.value==="dailyTokens"?(D=((Q=(H=s.usage)==null?void 0:H.daily)==null?void 0:Q.allTokens)||0,N=((z=(J=k.usage)==null?void 0:J.daily)==null?void 0:z.allTokens)||0):v.value==="dailyRequests"?(D=((te=(ee=s.usage)==null?void 0:ee.daily)==null?void 0:te.requests)||0,N=((Ue=(ae=k.usage)==null?void 0:ae.daily)==null?void 0:Ue.requests)||0):v.value==="totalTokens"&&(D=((Ve=(Ie=s.usage)==null?void 0:Ie.total)==null?void 0:Ve.allTokens)||0,N=((Se=(je=k.usage)==null?void 0:je.total)==null?void 0:Se.allTokens)||0),v.value==="lastUsed"&&(D=s.lastUsedAt?new Date(s.lastUsedAt).getTime():0,N=k.lastUsedAt?new Date(k.lastUsedAt).getTime():0),v.value==="status"&&(D=s.isActive?1:0,N=k.isActive?1:0),D<N?m.value==="asc"?-1:1:D>N?m.value==="asc"?1:-1:0}):o}),W=async()=>{T.value=!0;try{const[o,t,s,k,D]=await Promise.all([V.get("/admin/claude-accounts"),V.get("/admin/claude-console-accounts"),V.get("/admin/gemini-accounts"),V.get("/admin/api-keys"),V.get("/admin/account-groups")]);k.success&&(G.value=k.data||[]),D.success&&(R.value=D.data||[]);const N=new Map,H=new Map;for(const J of R.value){N.set(J.id,J);try{const z=await V.get(`/admin/account-groups/${J.id}/members`);z.success&&(z.data||[]).forEach(te=>{H.set(te.id,J)})}catch(z){console.error(`Failed to load members for group ${J.id}:`,z)}}const Q=[];if(o.success){const J=(o.data||[]).map(z=>{const ee=G.value.filter(ae=>ae.claudeAccountId===z.id).length,te=H.get(z.id)||null;return{...z,platform:"claude",boundApiKeysCount:ee,groupInfo:te}});Q.push(...J)}if(t.success){const J=(t.data||[]).map(z=>{const ee=H.get(z.id)||null;return{...z,platform:"claude-console",boundApiKeysCount:0,groupInfo:ee}});Q.push(...J)}if(s.success){const J=(s.data||[]).map(z=>{const ee=G.value.filter(ae=>ae.geminiAccountId===z.id).length,te=H.get(z.id)||null;return{...z,platform:"gemini",boundApiKeysCount:ee,groupInfo:te}});Q.push(...J)}I.value=Q,oe()}catch{h("加载账户失败","error")}finally{T.value=!1}},j=o=>{o&&(v.value===o?m.value=m.value==="asc"?"desc":"asc":(v.value=o,m.value="asc"))},u=o=>{if(o==null)return"0";const t=Number(o);return t>=1e6?Math.floor(t/1e6).toLocaleString()+"M":t.toLocaleString()},A=o=>{if(!o)return"从未使用";const t=new Date(o),k=new Date-t;return k<6e4?"刚刚":k<36e5?`${Math.floor(k/6e4)} 分钟前`:k<864e5?`${Math.floor(k/36e5)} 小时前`:k<6048e5?`${Math.floor(k/864e5)} 天前`:t.toLocaleDateString("zh-CN")},Z=async()=>{try{const o=await V.get("/admin/api-keys");o.success&&(G.value=o.data)}catch(o){console.error("Failed to load API keys:",o)}},oe=()=>{q.value==="all"?l.value=I.value:q.value==="ungrouped"?l.value=I.value.filter(o=>!o.groupInfo):l.value=I.value.filter(o=>o.groupInfo&&o.groupInfo.id===q.value)},c=o=>{if(!o||!o.host||!o.port)return null;const t=o.type==="socks5"?"S5":o.type.toUpperCase();let s=o.host;s.length>15&&(s=s.substring(0,12)+"...");let k=`${t}://${s}:${o.port}`;return o.username&&(k=`${t}://***@${s}:${o.port}`),k},p=(o,t)=>{if(!o||!t)return"--";const s=new Date(o),k=new Date(t),D=s.getHours().toString().padStart(2,"0"),N=s.getMinutes().toString().padStart(2,"0"),H=k.getHours().toString().padStart(2,"0"),Q=k.getMinutes().toString().padStart(2,"0");return`${D}:${N} - ${H}:${Q}`},U=o=>{if(!o||o<=0)return"已结束";const t=Math.floor(o/60),s=o%60;return t>0?`${t}小时${s}分钟`:`${s}分钟`},F=()=>{x.value=!0},ue=o=>{L.value=o,r.value=!0},de=async o=>{const t=G.value.filter(k=>k.claudeAccountId===o.id||k.geminiAccountId===o.id).length;if(t>0){h(`无法删除此账号,有 ${t} 个API Key绑定到此账号请先解绑所有API Key`,"error");return}if(await C("删除账户",`确定要删除账户 "${o.name}" 吗?
此操作不可恢复。`,"删除","取消"))try{let k;o.platform==="claude"?k=`/admin/claude-accounts/${o.id}`:o.platform==="claude-console"?k=`/admin/claude-console-accounts/${o.id}`:k=`/admin/gemini-accounts/${o.id}`;const D=await V.delete(k);D.success?(h("账户已删除","success"),W()):h(D.message||"删除失败","error")}catch{h("删除失败","error")}},ce=async o=>{if(!o.isRefreshing)try{o.isRefreshing=!0;const t=await V.post(`/admin/claude-accounts/${o.id}/refresh`);t.success?(h("Token刷新成功","success"),W()):h(t.message||"Token刷新失败","error")}catch{h("Token刷新失败","error")}finally{o.isRefreshing=!1}},pe=async o=>{if(!o.isTogglingSchedulable)try{o.isTogglingSchedulable=!0;let t;if(o.platform==="claude")t=`/admin/claude-accounts/${o.id}/toggle-schedulable`;else if(o.platform==="claude-console")t=`/admin/claude-console-accounts/${o.id}/toggle-schedulable`;else{h("Gemini账户暂不支持调度控制","warning");return}const s=await V.put(t);s.success?(o.schedulable=s.schedulable,h(s.schedulable?"已启用调度":"已禁用调度","success")):h(s.message||"操作失败","error")}catch{h("切换调度状态失败","error")}finally{o.isTogglingSchedulable=!1}},fe=()=>{x.value=!1,h("账户创建成功","success"),W()},xe=()=>{r.value=!1,h("账户更新成功","success"),W()},ve=o=>o.status==="blocked"?"已封锁":o.isRateLimited||o.status==="rate_limited"||o.rateLimitStatus&&o.rateLimitStatus.isRateLimited?"限流中":o.status==="error"||!o.isActive?"错误":o.schedulable===!1?"已暂停":"正常",ge=o=>o.status==="blocked"?"bg-red-100 text-red-800":o.isRateLimited||o.status==="rate_limited"||o.rateLimitStatus&&o.rateLimitStatus.isRateLimited?"bg-orange-100 text-orange-800":o.status==="error"||!o.isActive?"bg-red-100 text-red-800":o.schedulable===!1?"bg-gray-100 text-gray-800":"bg-green-100 text-green-800",ye=o=>o.status==="blocked"?"bg-red-500":o.isRateLimited||o.status==="rate_limited"||o.rateLimitStatus&&o.rateLimitStatus.isRateLimited?"bg-orange-500":o.status==="error"||!o.isActive?"bg-red-500":o.schedulable===!1?"bg-gray-500":"bg-green-500",be=o=>{if(!o.sessionWindow)return 100;const{remaining:t,total:s}=o.sessionWindow;return!s||s===0?100:Math.round(t/s*100)},we=o=>A(o),ke=async o=>{if(!S.value[o.id])try{S.value[o.id]=!0;const t=await V.post(`/admin/claude-accounts/${o.id}/refresh`);t.success?(h("Token刷新成功","success"),W()):h(t.message||"Token刷新失败","error")}catch{h("Token刷新失败","error")}finally{S.value[o.id]=!1}};return E(w,o=>{const t={name:"name",dailyTokens:"dailyTokens",dailyRequests:"dailyRequests",totalTokens:"totalTokens",lastUsed:"lastUsed"};t[o]&&j(t[o])}),Re(()=>{W(),Z()}),(o,t)=>(a(),n("div",Pl,[e("div",Dl,[e("div",zl,[t[13]||(t[13]=e("div",null,[e("h3",{class:"text-lg sm:text-xl font-bold text-gray-900 mb-1 sm:mb-2"}," 账户管理 "),e("p",{class:"text-sm sm:text-base text-gray-600"}," 管理您的 Claude 和 Gemini 账户及代理配置 ")],-1)),e("div",El,[e("div",Ol,[g(e("select",{"onUpdate:modelValue":t[0]||(t[0]=s=>w.value=s),class:"form-input px-3 py-2 text-sm w-full sm:w-auto",onChange:t[1]||(t[1]=s=>j())},t[9]||(t[9]=[Ce('<option value="name" data-v-ab3ae7fd> 按名称排序 </option><option value="dailyTokens" data-v-ab3ae7fd> 按今日Token排序 </option><option value="dailyRequests" data-v-ab3ae7fd> 按今日请求数排序 </option><option value="totalTokens" data-v-ab3ae7fd> 按总Token排序 </option><option value="lastUsed" data-v-ab3ae7fd> 按最后使用排序 </option>',5)]),544),[[me,w.value]]),g(e("select",{"onUpdate:modelValue":t[2]||(t[2]=s=>q.value=s),class:"form-input px-3 py-2 text-sm w-full sm:w-auto",onChange:oe},[t[10]||(t[10]=e("option",{value:"all"},"所有账户",-1)),t[11]||(t[11]=e("option",{value:"ungrouped"},"未分组账户",-1)),(a(!0),n(re,null,ie(R.value,s=>(a(),n("option",{key:s.id,value:s.id},f(s.name)+" ("+f(s.platform==="claude"?"Claude":"Gemini")+") ",9,Wl))),128))],544),[[me,q.value]])]),e("button",{class:"btn btn-success px-4 sm:px-6 py-2 sm:py-3 flex items-center gap-2 w-full sm:w-auto justify-center",onClick:We(F,["stop"])},t[12]||(t[12]=[e("i",{class:"fas fa-plus"},null,-1),$("添加账户 ",-1)]))])]),T.value?(a(),n("div",ql,t[14]||(t[14]=[e("div",{class:"loading-spinner mx-auto mb-4"},null,-1),e("p",{class:"text-gray-500"}," 正在加载账户... ",-1)]))):B.value.length===0?(a(),n("div",Bl,t[15]||(t[15]=[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-user-circle text-gray-400 text-xl"})],-1),e("p",{class:"text-gray-500 text-lg"}," 暂无账户 ",-1),e("p",{class:"text-gray-400 text-sm mt-2"}," 点击上方按钮添加您的第一个账户 ",-1)]))):(a(),n("div",Fl,[e("table",Nl,[e("thead",Hl,[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-[22%] min-w-[180px]",onClick:t[3]||(t[3]=s=>j("name"))},[t[16]||(t[16]=$(" 名称 ",-1)),v.value==="name"?(a(),n("i",{key:0,class:K(["fas",m.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(a(),n("i",Jl))]),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-[15%] min-w-[120px]",onClick:t[4]||(t[4]=s=>j("platform"))},[t[17]||(t[17]=$(" 平台/类型 ",-1)),v.value==="platform"?(a(),n("i",{key:0,class:K(["fas",m.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(a(),n("i",Yl))]),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-[12%] min-w-[100px]",onClick:t[5]||(t[5]=s=>j("status"))},[t[18]||(t[18]=$(" 状态 ",-1)),v.value==="status"?(a(),n("i",{key:0,class:K(["fas",m.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(a(),n("i",Ql))]),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-[80px]",onClick:t[6]||(t[6]=s=>j("priority"))},[t[19]||(t[19]=$(" 优先级 ",-1)),v.value==="priority"?(a(),n("i",{key:0,class:K(["fas",m.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(a(),n("i",Xl))]),t[20]||(t[20]=e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider w-[10%] min-w-[100px]"}," 代理 ",-1)),t[21]||(t[21]=e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider w-[10%] min-w-[90px]"}," 今日使用 ",-1)),t[22]||(t[22]=e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider w-[10%] min-w-[100px]"}," 会话窗口 ",-1)),t[23]||(t[23]=e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider w-[8%] min-w-[80px]"}," 最后使用 ",-1)),t[24]||(t[24]=e("th",{class:"px-3 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider w-[15%] min-w-[180px]"}," 操作 ",-1))])]),e("tbody",Zl,[(a(!0),n(re,null,ie(B.value,s=>(a(),n("tr",{key:s.id,class:"table-row"},[e("td",eo,[e("div",to,[t[29]||(t[29]=e("div",{class:"w-8 h-8 bg-gradient-to-br from-green-500 to-green-600 rounded-lg flex items-center justify-center mr-2 flex-shrink-0"},[e("i",{class:"fas fa-user-circle text-white text-xs"})],-1)),e("div",so,[e("div",lo,[e("div",{class:"text-sm font-semibold text-gray-900 truncate",title:s.name},f(s.name),9,oo),s.accountType==="dedicated"?(a(),n("span",ao,t[25]||(t[25]=[e("i",{class:"fas fa-lock mr-1"},null,-1),$("专属 ",-1)]))):s.accountType==="group"?(a(),n("span",no,t[26]||(t[26]=[e("i",{class:"fas fa-layer-group mr-1"},null,-1),$("分组调度 ",-1)]))):(a(),n("span",ro,t[27]||(t[27]=[e("i",{class:"fas fa-share-alt mr-1"},null,-1),$("共享 ",-1)]))),s.groupInfo?(a(),n("span",{key:3,class:"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600 ml-1",title:`所属分组: ${s.groupInfo.name}`},[t[28]||(t[28]=e("i",{class:"fas fa-folder mr-1"},null,-1)),$(f(s.groupInfo.name),1)],8,io)):y("",!0)]),e("div",{class:"text-xs text-gray-500 truncate",title:s.id},f(s.id),9,uo)])])]),e("td",po,[e("div",mo,[s.platform==="gemini"?(a(),n("div",co,[t[30]||(t[30]=e("i",{class:"fas fa-robot text-yellow-700 text-xs"},null,-1)),t[31]||(t[31]=e("span",{class:"text-xs font-semibold text-yellow-800"},"Gemini",-1)),t[32]||(t[32]=e("span",{class:"w-px h-4 bg-yellow-300 mx-1"},null,-1)),e("span",fo,f(s.scopes&&s.scopes.length>0?"OAuth":"传统"),1)])):s.platform==="claude-console"?(a(),n("div",xo,t[33]||(t[33]=[e("i",{class:"fas fa-terminal text-purple-700 text-xs"},null,-1),e("span",{class:"text-xs font-semibold text-purple-800"},"Console",-1),e("span",{class:"w-px h-4 bg-purple-300 mx-1"},null,-1),e("span",{class:"text-xs font-medium text-purple-700"},"API Key",-1)]))):(a(),n("div",vo,[t[34]||(t[34]=e("i",{class:"fas fa-brain text-indigo-700 text-xs"},null,-1)),t[35]||(t[35]=e("span",{class:"text-xs font-semibold text-indigo-800"},"Claude",-1)),t[36]||(t[36]=e("span",{class:"w-px h-4 bg-indigo-300 mx-1"},null,-1)),e("span",go,f(s.scopes&&s.scopes.length>0?"OAuth":"传统"),1)]))])]),e("td",yo,[e("div",bo,[e("span",{class:K(["inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold",s.status==="blocked"?"bg-orange-100 text-orange-800":s.isActive?"bg-green-100 text-green-800":"bg-red-100 text-red-800"])},[e("div",{class:K(["w-2 h-2 rounded-full mr-2",s.status==="blocked"?"bg-orange-500":s.isActive?"bg-green-500":"bg-red-500"])},null,2),$(" "+f(s.status==="blocked"?"已封锁":s.isActive?"正常":"异常"),1)],2),s.rateLimitStatus&&s.rateLimitStatus.isRateLimited?(a(),n("span",wo,[t[37]||(t[37]=e("i",{class:"fas fa-exclamation-triangle mr-1"},null,-1)),$(" 限流中 ("+f(s.rateLimitStatus.minutesRemaining)+"分钟) ",1)])):y("",!0),s.schedulable===!1?(a(),n("span",ko,t[38]||(t[38]=[e("i",{class:"fas fa-pause-circle mr-1"},null,-1),$(" 不可调度 ",-1)]))):y("",!0),s.status==="blocked"&&s.errorMessage?(a(),n("span",{key:2,class:"text-xs text-gray-500 mt-1 max-w-xs truncate",title:s.errorMessage},f(s.errorMessage),9,ho)):y("",!0),s.accountType==="dedicated"?(a(),n("span",$o," 绑定: "+f(s.boundApiKeysCount||0)+" 个API Key ",1)):y("",!0)])]),e("td",Co,[s.platform==="claude"||s.platform==="claude-console"?(a(),n("div",To,[e("div",Ao,[e("div",{class:"bg-gradient-to-r from-green-500 to-blue-600 h-2 rounded-full transition-all duration-300",style:Te({width:101-(s.priority||50)+"%"})},null,4)]),e("span",Uo,f(s.priority||50),1)])):(a(),n("div",Io,t[39]||(t[39]=[e("span",{class:"text-xs"},"N/A",-1)])))]),e("td",Vo,[c(s.proxy)?(a(),n("div",{key:0,class:"text-xs bg-blue-50 px-2 py-1 rounded font-mono break-all",title:c(s.proxy)},f(c(s.proxy)),9,jo)):(a(),n("div",So," 无代理 "))]),e("td",_o,[s.usage&&s.usage.daily?(a(),n("div",Mo,[e("div",Go,[t[40]||(t[40]=e("div",{class:"w-2 h-2 bg-green-500 rounded-full"},null,-1)),e("span",Ko,f(s.usage.daily.requests||0)+" 次",1)]),e("div",Ro,[t[41]||(t[41]=e("div",{class:"w-2 h-2 bg-blue-500 rounded-full"},null,-1)),e("span",Lo,f(u(s.usage.daily.allTokens||0))+" tokens",1)]),s.usage.averages&&s.usage.averages.rpm>0?(a(),n("div",Po," 平均 "+f(s.usage.averages.rpm.toFixed(2))+" RPM ",1)):y("",!0)])):(a(),n("div",Do," 暂无数据 "))]),e("td",zo,[s.platform==="claude"&&s.sessionWindow&&s.sessionWindow.hasActiveWindow?(a(),n("div",Eo,[e("div",Oo,[e("div",Wo,[e("div",{class:"bg-gradient-to-r from-blue-500 to-indigo-600 h-2 rounded-full transition-all duration-300",style:Te({width:s.sessionWindow.progress+"%"})},null,4)]),e("span",qo,f(s.sessionWindow.progress)+"% ",1)]),e("div",Bo,[e("div",null,f(p(s.sessionWindow.windowStart,s.sessionWindow.windowEnd)),1),s.sessionWindow.remainingTime>0?(a(),n("div",Fo," 剩余 "+f(U(s.sessionWindow.remainingTime)),1)):y("",!0)])])):s.platform==="claude"?(a(),n("div",No,t[42]||(t[42]=[e("i",{class:"fas fa-minus"},null,-1)]))):(a(),n("div",Ho,t[43]||(t[43]=[e("span",{class:"text-xs"},"N/A",-1)])))]),e("td",Jo,f(A(s.lastUsedAt)),1),e("td",Yo,[e("div",Qo,[s.platform==="claude"&&s.scopes?(a(),n("button",{key:0,disabled:s.isRefreshing,class:K(["px-2.5 py-1 rounded text-xs font-medium transition-colors",s.isRefreshing?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-blue-100 text-blue-700 hover:bg-blue-200"]),title:s.isRefreshing?"刷新中...":"刷新Token",onClick:k=>ce(s)},[e("i",{class:K(["fas fa-sync-alt",s.isRefreshing?"animate-spin":""])},null,2),t[44]||(t[44]=e("span",{class:"ml-1"},"刷新",-1))],10,Xo)):y("",!0),e("button",{disabled:s.isTogglingSchedulable,class:K(["px-2.5 py-1 rounded text-xs font-medium transition-colors",s.isTogglingSchedulable?"bg-gray-100 text-gray-400 cursor-not-allowed":s.schedulable?"bg-green-100 text-green-700 hover:bg-green-200":"bg-gray-100 text-gray-700 hover:bg-gray-200"]),title:s.schedulable?"点击禁用调度":"点击启用调度",onClick:k=>pe(s)},[e("i",{class:K(["fas",s.schedulable?"fa-toggle-on":"fa-toggle-off"])},null,2),e("span",ea,f(s.schedulable?"调度":"停用"),1)],10,Zo),e("button",{class:"px-2.5 py-1 bg-blue-100 text-blue-700 rounded text-xs font-medium hover:bg-blue-200 transition-colors",title:"编辑账户",onClick:k=>ue(s)},t[45]||(t[45]=[e("i",{class:"fas fa-edit"},null,-1),e("span",{class:"ml-1"},"编辑",-1)]),8,ta),e("button",{class:"px-2.5 py-1 bg-red-100 text-red-700 rounded text-xs font-medium hover:bg-red-200 transition-colors",title:"删除账户",onClick:k=>de(s)},t[46]||(t[46]=[e("i",{class:"fas fa-trash"},null,-1),e("span",{class:"ml-1"},"删除",-1)]),8,sa)])])]))),128))])])])),!T.value&&B.value.length>0?(a(),n("div",la,[(a(!0),n(re,null,ie(B.value,s=>{var k,D,N,H;return a(),n("div",{key:s.id,class:"card p-4 hover:shadow-lg transition-shadow"},[e("div",oa,[e("div",aa,[e("div",{class:K(["w-10 h-10 rounded-lg flex items-center justify-center flex-shrink-0",s.platform==="claude"?"bg-gradient-to-br from-purple-500 to-purple-600":"bg-gradient-to-br from-blue-500 to-blue-600"])},[e("i",{class:K(["text-white text-sm",s.platform==="claude"?"fas fa-brain":"fas fa-robot"])},null,2)],2),e("div",null,[e("h4",na,f(s.name||s.email),1),e("div",ra,[e("span",ia,f(s.platform),1),t[47]||(t[47]=e("span",{class:"text-xs text-gray-400"},"|",-1)),e("span",ua,f(s.type),1)])])]),e("span",{class:K(["inline-flex items-center px-2 py-1 rounded-full text-xs font-semibold",ge(s)])},[e("div",{class:K(["w-1.5 h-1.5 rounded-full mr-1.5",ye(s)])},null,2),$(" "+f(ve(s)),1)],2)]),e("div",da,[e("div",null,[t[48]||(t[48]=e("p",{class:"text-xs text-gray-500"}," 今日使用 ",-1)),e("p",pa,f(u(((k=s.usage)==null?void 0:k.dailyRequests)||0))+" 次 ",1),e("p",ma,f(u(((D=s.usage)==null?void 0:D.dailyTokens)||0))+" tokens ",1)]),e("div",null,[t[49]||(t[49]=e("p",{class:"text-xs text-gray-500"}," 总使用量 ",-1)),e("p",ca,f(u(((N=s.usage)==null?void 0:N.totalRequests)||0))+" 次 ",1),e("p",fa,f(u(((H=s.usage)==null?void 0:H.totalTokens)||0))+" tokens ",1)])]),e("div",xa,[s.sessionWindow?(a(),n("div",va,[t[50]||(t[50]=e("span",{class:"text-gray-500"},"会话窗口",-1)),e("div",ga,[e("span",{class:K(["font-medium",s.sessionWindow.remaining<=20?"text-orange-600":"text-gray-900"])},f(s.sessionWindow.remaining||0)+" / "+f(s.sessionWindow.total||0),3),e("div",ya,[e("div",{class:"h-full bg-gradient-to-r from-blue-500 to-blue-600 transition-all duration-300",style:Te({width:`${be(s)}%`})},null,4)])])])):y("",!0),e("div",ba,[t[51]||(t[51]=e("span",{class:"text-gray-500"},"最后使用",-1)),e("span",wa,f(s.lastUsedAt?we(s.lastUsedAt):"从未使用"),1)]),s.proxyConfig&&s.proxyConfig.type!=="none"?(a(),n("div",ka,[t[52]||(t[52]=e("span",{class:"text-gray-500"},"代理",-1)),e("span",ha,f(s.proxyConfig.type.toUpperCase()),1)])):y("",!0),e("div",$a,[t[53]||(t[53]=e("span",{class:"text-gray-500"},"优先级",-1)),e("span",Ca,f(s.priority||0),1)])]),e("div",Ta,[s.platform==="claude"&&s.type==="oauth"?(a(),n("button",{key:0,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",disabled:S.value[s.id],onClick:Q=>ke(s)},[e("i",{class:K(["fas fa-sync-alt",{"animate-spin":S.value[s.id]}])},null,2),$(" "+f(S.value[s.id]?"刷新中":"刷新"),1)],8,Aa)):y("",!0),e("button",{class:K(["flex-1 px-3 py-2 text-xs rounded-lg transition-colors flex items-center justify-center gap-1",s.schedulable?"text-gray-600 bg-gray-50 hover:bg-gray-100":"text-green-600 bg-green-50 hover:bg-green-100"]),onClick:Q=>pe(s),disabled:s.isTogglingSchedulable},[e("i",{class:K(["fas",s.schedulable?"fa-pause":"fa-play"])},null,2),$(" "+f(s.schedulable?"暂停":"启用"),1)],10,Ua),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:Q=>ue(s)},t[54]||(t[54]=[e("i",{class:"fas fa-edit mr-1"},null,-1),$(" 编辑 ",-1)]),8,Ia),e("button",{class:"px-3 py-2 text-xs text-red-600 bg-red-50 rounded-lg hover:bg-red-100 transition-colors",onClick:Q=>de(s)},t[55]||(t[55]=[e("i",{class:"fas fa-trash"},null,-1)]),8,Va)])])}),128))])):y("",!0)]),x.value?(a(),le(Ke,{key:0,onClose:t[7]||(t[7]=s=>x.value=!1),onSuccess:fe})):y("",!0),r.value?(a(),le(Ke,{key:1,account:L.value,onClose:t[8]||(t[8]=s=>r.value=!1),onSuccess:xe},null,8,["account"])):y("",!0),$e(De,{show:Y(O),title:Y(d).title,message:Y(d).message,"confirm-text":Y(d).confirmText,"cancel-text":Y(d).cancelText,onConfirm:Y(i),onCancel:Y(M)},null,8,["show","title","message","confirm-text","cancel-text","onConfirm","onCancel"])]))}},Ra=qe(ja,[["__scopeId","data-v-ab3ae7fd"]]);export{Ra as default};