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

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