Files
claude-relay-service/web/admin-spa/dist/assets/AccountsView-BJCyk-bV.js
shaw 19cab40b77 feat(admin-spa): 添加构建后的dist目录并更新.gitignore
- 添加 admin-spa 构建后的 dist 目录
- 从 .gitignore 中移除 dist 忽略规则
- 确保 /admin-next 路由可以正常访问

现在访问 /admin-next/api-stats 将能正确加载新版管理界面

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 12:48:15 +08:00

8 lines
52 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{aR as fe,r as b,o as K,x as u,y as r,z as e,L as T,K as h,al as re,aY as O,aX as ce,aq as G,aZ as xe,C as P,O as g,c as B,P as C,I as N,a5 as me,R as X,an as D,u as L,q as ve,Y as ye,Q as ge,ac as be,B as we}from"./vue-vendor-YmkKLAOK.js";import{s as A}from"./toast-BvwA7Mwb.js";import{a as _,_ as ke}from"./index-15K8yWyh.js";import"./element-plus-D-FTEVKS.js";import"./vendor-BDiMbLwQ.js";const pe=fe("accounts",()=>{const U=b([]),V=b([]),i=b(!1),x=b(null),m=b(""),y=b("asc"),w=async()=>{i.value=!0,x.value=null;try{const p=await _.get("/admin/claude-accounts");if(p.success)U.value=p.data||[];else throw new Error(p.message||"获取Claude账户失败")}catch(p){throw x.value=p.message,p}finally{i.value=!1}},v=async()=>{i.value=!0,x.value=null;try{const p=await _.get("/admin/gemini-accounts");if(p.success)V.value=p.data||[];else throw new Error(p.message||"获取Gemini账户失败")}catch(p){throw x.value=p.message,p}finally{i.value=!1}};return{claudeAccounts:U,geminiAccounts:V,loading:i,error:x,sortBy:m,sortOrder:y,fetchClaudeAccounts:w,fetchGeminiAccounts:v,fetchAllAccounts:async()=>{i.value=!0,x.value=null;try{await Promise.all([w(),v()])}catch(p){throw x.value=p.message,p}finally{i.value=!1}},createClaudeAccount:async p=>{i.value=!0,x.value=null;try{const o=await _.post("/admin/claude-accounts",p);if(o.success)return await w(),o.data;throw new Error(o.message||"创建Claude账户失败")}catch(o){throw x.value=o.message,o}finally{i.value=!1}},createGeminiAccount:async p=>{i.value=!0,x.value=null;try{const o=await _.post("/admin/gemini-accounts",p);if(o.success)return await v(),o.data;throw new Error(o.message||"创建Gemini账户失败")}catch(o){throw x.value=o.message,o}finally{i.value=!1}},updateClaudeAccount:async(p,o)=>{i.value=!0,x.value=null;try{const s=await _.put(`/admin/claude-accounts/${p}`,o);if(s.success)return await w(),s;throw new Error(s.message||"更新Claude账户失败")}catch(s){throw x.value=s.message,s}finally{i.value=!1}},updateGeminiAccount:async(p,o)=>{i.value=!0,x.value=null;try{const s=await _.put(`/admin/gemini-accounts/${p}`,o);if(s.success)return await v(),s;throw new Error(s.message||"更新Gemini账户失败")}catch(s){throw x.value=s.message,s}finally{i.value=!1}},toggleAccount:async(p,o)=>{i.value=!0,x.value=null;try{const s=p==="claude"?`/admin/claude-accounts/${o}/toggle`:`/admin/gemini-accounts/${o}/toggle`,a=await _.put(s);if(a.success)return p==="claude"?await w():await v(),a;throw new Error(a.message||"切换状态失败")}catch(s){throw x.value=s.message,s}finally{i.value=!1}},deleteAccount:async(p,o)=>{i.value=!0,x.value=null;try{const s=p==="claude"?`/admin/claude-accounts/${o}`:`/admin/gemini-accounts/${o}`,a=await _.delete(s);if(a.success)return p==="claude"?await w():await v(),a;throw new Error(a.message||"删除失败")}catch(s){throw x.value=s.message,s}finally{i.value=!1}},refreshClaudeToken:async p=>{i.value=!0,x.value=null;try{const o=await _.post(`/admin/claude-accounts/${p}/refresh`);if(o.success)return await w(),o;throw new Error(o.message||"Token刷新失败")}catch(o){throw x.value=o.message,o}finally{i.value=!1}},generateClaudeAuthUrl:async p=>{try{const o=await _.post("/admin/claude-accounts/generate-auth-url",p);if(o.success)return o.data.authUrl;throw new Error(o.message||"生成授权URL失败")}catch(o){throw x.value=o.message,o}},exchangeClaudeCode:async p=>{try{const o=await _.post("/admin/claude-accounts/exchange-code",p);if(o.success)return o.data;throw new Error(o.message||"交换授权码失败")}catch(o){throw x.value=o.message,o}},generateGeminiAuthUrl:async p=>{try{const o=await _.post("/admin/gemini-accounts/generate-auth-url",p);if(o.success)return o.data.authUrl;throw new Error(o.message||"生成授权URL失败")}catch(o){throw x.value=o.message,o}},exchangeGeminiCode:async p=>{try{const o=await _.post("/admin/gemini-accounts/exchange-code",p);if(o.success)return o.data;throw new Error(o.message||"交换授权码失败")}catch(o){throw x.value=o.message,o}},sortAccounts:p=>{m.value===p?y.value=y.value==="asc"?"desc":"asc":(m.value=p,y.value="asc")},reset:()=>{U.value=[],V.value=[],i.value=!1,x.value=null,m.value="",y.value="asc"}}}),Q=b(!1),ie=b({title:"",message:"",confirmText:"继续",cancelText:"取消"}),W=b(null);function he(){return{showConfirmModal:Q,confirmOptions:ie,showConfirm:(x,m,y="继续",w="取消")=>new Promise(v=>{ie.value={title:x,message:m,confirmText:y,cancelText:w},W.value=v,Q.value=!0}),handleConfirm:()=>{Q.value=!1,W.value&&(W.value(!0),W.value=null)},handleCancel:()=>{Q.value=!1,W.value&&(W.value(!1),W.value=null)}}}const $e={class:"space-y-4"},Te={class:"flex items-center justify-between"},Ce={class:"flex items-center cursor-pointer"},Ae={key:0,class:"bg-gray-50 p-4 rounded-lg border border-gray-200 space-y-4"},Ue={class:"grid grid-cols-2 gap-4"},je={class:"space-y-4"},Se={class:"flex items-center"},_e={key:0,class:"grid grid-cols-2 gap-4"},Ve={class:"relative"},Ge=["type"],ue={__name:"ProxyConfig",props:{modelValue:{type:Object,default:()=>({enabled:!1,type:"socks5",host:"",port:"",username:"",password:""})}},emits:["update:modelValue"],setup(U,{emit:V}){const i=U,x=V,m=b({...i.modelValue}),y=b(!!(m.value.username||m.value.password)),w=b(!1);return K(()=>i.modelValue,v=>{m.value={...v},y.value=!!(v.username||v.password)},{deep:!0}),K(m,v=>{y.value||(v.username="",v.password=""),x("update:modelValue",{...v})},{deep:!0}),K(y,v=>{v||(m.value.username="",m.value.password="")}),(v,c)=>(r(),u("div",$e,[e("div",Te,[c[9]||(c[9]=e("h4",{class:"text-sm font-semibold text-gray-700"},"代理设置 (可选)",-1)),e("label",Ce,[h(e("input",{type:"checkbox","onUpdate:modelValue":c[0]||(c[0]=$=>m.value.enabled=$),class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[re,m.value.enabled]]),c[8]||(c[8]=e("span",{class:"ml-2 text-sm text-gray-700"},"启用代理",-1))])]),m.value.enabled?(r(),u("div",Ae,[c[17]||(c[17]=O('<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,[c[11]||(c[11]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"代理类型",-1)),h(e("select",{"onUpdate:modelValue":c[1]||(c[1]=$=>m.value.type=$),class:"form-input w-full"},c[10]||(c[10]=[e("option",{value:"socks5"},"SOCKS5",-1),e("option",{value:"http"},"HTTP",-1),e("option",{value:"https"},"HTTPS",-1)]),512),[[ce,m.value.type]])]),e("div",Ue,[e("div",null,[c[12]||(c[12]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"主机地址",-1)),h(e("input",{"onUpdate:modelValue":c[2]||(c[2]=$=>m.value.host=$),type:"text",placeholder:"例如: 192.168.1.100",class:"form-input w-full"},null,512),[[G,m.value.host]])]),e("div",null,[c[13]||(c[13]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"端口",-1)),h(e("input",{"onUpdate:modelValue":c[3]||(c[3]=$=>m.value.port=$),type:"number",placeholder:"例如: 1080",class:"form-input w-full"},null,512),[[G,m.value.port]])])]),e("div",je,[e("div",Se,[h(e("input",{type:"checkbox","onUpdate:modelValue":c[4]||(c[4]=$=>y.value=$),id:"proxyAuth",class:"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"},null,512),[[re,y.value]]),c[14]||(c[14]=e("label",{for:"proxyAuth",class:"ml-2 text-sm text-gray-700 cursor-pointer"}," 需要身份验证 ",-1))]),y.value?(r(),u("div",_e,[e("div",null,[c[15]||(c[15]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"用户名",-1)),h(e("input",{"onUpdate:modelValue":c[5]||(c[5]=$=>m.value.username=$),type:"text",placeholder:"代理用户名",class:"form-input w-full"},null,512),[[G,m.value.username]])]),e("div",null,[c[16]||(c[16]=e("label",{class:"block text-sm font-medium text-gray-700 mb-2"},"密码",-1)),e("div",Ve,[h(e("input",{"onUpdate:modelValue":c[6]||(c[6]=$=>m.value.password=$),type:w.value?"text":"password",placeholder:"代理密码",class:"form-input w-full pr-10"},null,8,Ge),[[xe,m.value.password]]),e("button",{type:"button",onClick:c[7]||(c[7]=$=>w.value=!w.value),class:"absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-gray-600"},[e("i",{class:P(w.value?"fas fa-eye-slash":"fas fa-eye")},null,2)])])])])):T("",!0)]),c[18]||(c[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,"提示:"),g("代理设置将用于所有与此账户相关的API请求。请确保代理服务器支持HTTPS流量转发。 ")])],-1))])):T("",!0)]))}},Ie={class:"space-y-6"},Re={key:0},Me={class:"bg-blue-50 p-6 rounded-lg border border-blue-200"},Pe={class:"flex items-start gap-4"},ze={class:"flex-1"},Ee={class:"space-y-4"},De={class:"bg-white/80 rounded-lg p-4 border border-blue-300"},Le={class:"flex items-start gap-3"},We={class:"flex-1"},qe=["disabled"],Ke={key:0,class:"fas fa-link mr-2"},Oe={key:1,class:"loading-spinner mr-2"},Be={key:1,class:"space-y-3"},Ne={class:"flex items-center gap-2"},He=["value"],Fe={class:"bg-white/80 rounded-lg p-4 border border-blue-300"},Ye={class:"flex items-start gap-3"},Qe={class:"flex-1"},Xe={class:"space-y-3"},Ze={key:1},Je={class:"bg-green-50 p-6 rounded-lg border border-green-200"},et={class:"flex items-start gap-4"},tt={class:"flex-1"},st={class:"space-y-4"},lt={class:"bg-white/80 rounded-lg p-4 border border-green-300"},ot={class:"flex items-start gap-3"},at={class:"flex-1"},nt=["disabled"],rt={key:0,class:"fas fa-link mr-2"},it={key:1,class:"loading-spinner mr-2"},ut={key:1,class:"space-y-3"},dt={class:"flex items-center gap-2"},ct=["value"],mt={class:"bg-white/80 rounded-lg p-4 border border-green-300"},pt={class:"flex items-start gap-3"},ft={class:"flex-1"},xt={class:"space-y-3"},vt={class:"flex gap-3 pt-4"},yt=["disabled"],gt={key:0,class:"loading-spinner mr-2"},bt={__name:"OAuthFlow",props:{platform:{type:String,required:!0},proxy:{type:Object,default:null}},emits:["success","back"],setup(U,{emit:V}){const i=U,x=V,m=pe(),y=b(!1),w=b(!1),v=b(""),c=b(""),$=b(!1),R=B(()=>v.value&&c.value.trim()),z=async()=>{var I;y.value=!0;try{const n=(I=i.proxy)!=null&&I.enabled?{type:i.proxy.type,host:i.proxy.host,port:i.proxy.port,username:i.proxy.username,password:i.proxy.password}:null;i.platform==="claude"?v.value=await m.generateClaudeAuthUrl(n):i.platform==="gemini"&&(v.value=await m.generateGeminiAuthUrl(n))}catch(n){A(n.message||"生成授权链接失败","error")}finally{y.value=!1}},j=()=>{v.value="",c.value="",z()},S=async()=>{try{await navigator.clipboard.writeText(v.value),$.value=!0,A("链接已复制","success"),setTimeout(()=>{$.value=!1},2e3)}catch{const n=document.createElement("input");n.value=v.value,document.body.appendChild(n),n.select(),document.execCommand("copy"),document.body.removeChild(n),$.value=!0,A("链接已复制","success"),setTimeout(()=>{$.value=!1},2e3)}},l=async()=>{var I;if(R.value){w.value=!0;try{const n={code:c.value.trim()};(I=i.proxy)!=null&&I.enabled&&(n.proxy={type:i.proxy.type,host:i.proxy.host,port:i.proxy.port,username:i.proxy.username,password:i.proxy.password});let M;i.platform==="claude"?M=await m.exchangeClaudeCode(n):i.platform==="gemini"&&(M=await m.exchangeGeminiCode(n)),x("success",M)}catch(n){A(n.message||"授权失败,请检查授权码是否正确","error")}finally{w.value=!1}}};return(I,n)=>(r(),u("div",Ie,[U.platform==="claude"?(r(),u("div",Re,[e("div",Me,[e("div",Pe,[n[14]||(n[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",ze,[n[12]||(n[12]=e("h4",{class:"font-semibold text-blue-900 mb-3"},"Claude 账户授权",-1)),n[13]||(n[13]=e("p",{class:"text-sm text-blue-800 mb-4"}," 请按照以下步骤完成 Claude 账户的授权: ",-1)),e("div",Ee,[e("div",De,[e("div",Le,[n[5]||(n[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",We,[n[4]||(n[4]=e("p",{class:"font-medium text-blue-900 mb-2"},"点击下方按钮生成授权链接",-1)),v.value?(r(),u("div",Be,[e("div",Ne,[e("input",{type:"text",value:v.value,readonly:"",class:"form-input flex-1 text-xs font-mono bg-gray-50"},null,8,He),e("button",{onClick:S,class:"px-3 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors",title:"复制链接"},[e("i",{class:P($.value?"fas fa-check text-green-500":"fas fa-copy")},null,2)])]),e("button",{onClick:j,class:"text-xs text-blue-600 hover:text-blue-700"},n[3]||(n[3]=[e("i",{class:"fas fa-sync-alt mr-1"},null,-1),g("重新生成 ",-1)]))])):(r(),u("button",{key:0,onClick:z,disabled:y.value,class:"btn btn-primary px-4 py-2 text-sm"},[y.value?(r(),u("div",Oe)):(r(),u("i",Ke)),g(" "+C(y.value?"生成中...":"生成授权链接"),1)],8,qe))])])]),n[11]||(n[11]=O('<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",Fe,[e("div",Ye,[n[10]||(n[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",Qe,[n[8]||(n[8]=e("p",{class:"font-medium text-blue-900 mb-2"},"输入 Authorization Code",-1)),n[9]||(n[9]=e("p",{class:"text-sm text-blue-700 mb-3"},[g(" 授权完成后,页面会显示一个 "),e("strong",null,"Authorization Code"),g(",请将其复制并粘贴到下方输入框: ")],-1)),e("div",Xe,[e("div",null,[n[6]||(n[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"}),g("Authorization Code ")],-1)),h(e("textarea",{"onUpdate:modelValue":n[0]||(n[0]=M=>c.value=M),rows:"3",class:"form-input w-full resize-none font-mono text-sm",placeholder:"粘贴从Claude页面获取的Authorization Code..."},null,512),[[G,c.value]])]),n[7]||(n[7]=e("p",{class:"text-xs text-gray-500 mt-2"},[e("i",{class:"fas fa-info-circle mr-1"}),g(" 请粘贴从Claude页面复制的Authorization Code ")],-1))])])])])])])])])])):U.platform==="gemini"?(r(),u("div",Ze,[e("div",Je,[e("div",et,[n[26]||(n[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",tt,[n[24]||(n[24]=e("h4",{class:"font-semibold text-green-900 mb-3"},"Gemini 账户授权",-1)),n[25]||(n[25]=e("p",{class:"text-sm text-green-800 mb-4"}," 请按照以下步骤完成 Gemini 账户的授权: ",-1)),e("div",st,[e("div",lt,[e("div",ot,[n[17]||(n[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",at,[n[16]||(n[16]=e("p",{class:"font-medium text-green-900 mb-2"},"点击下方按钮生成授权链接",-1)),v.value?(r(),u("div",ut,[e("div",dt,[e("input",{type:"text",value:v.value,readonly:"",class:"form-input flex-1 text-xs font-mono bg-gray-50"},null,8,ct),e("button",{onClick:S,class:"px-3 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors",title:"复制链接"},[e("i",{class:P($.value?"fas fa-check text-green-500":"fas fa-copy")},null,2)])]),e("button",{onClick:j,class:"text-xs text-green-600 hover:text-green-700"},n[15]||(n[15]=[e("i",{class:"fas fa-sync-alt mr-1"},null,-1),g("重新生成 ",-1)]))])):(r(),u("button",{key:0,onClick:z,disabled:y.value,class:"btn btn-primary px-4 py-2 text-sm"},[y.value?(r(),u("div",it)):(r(),u("i",rt)),g(" "+C(y.value?"生成中...":"生成授权链接"),1)],8,nt))])])]),n[23]||(n[23]=O('<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",mt,[e("div",pt,[n[22]||(n[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",ft,[n[20]||(n[20]=e("p",{class:"font-medium text-green-900 mb-2"},"复制oauth后的链接",-1)),n[21]||(n[21]=e("p",{class:"text-sm text-green-700 mb-3"}," 复制浏览器地址栏的完整链接并粘贴到下方输入框: ",-1)),e("div",xt,[e("div",null,[n[18]||(n[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"}),g("复制oauth后的链接 ")],-1)),h(e("textarea",{"onUpdate:modelValue":n[1]||(n[1]=M=>c.value=M),rows:"3",class:"form-input w-full resize-none font-mono text-sm",placeholder:"粘贴以 http://localhost:45462 开头的完整链接..."},null,512),[[G,c.value]])]),n[19]||(n[19]=O('<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))])])])])])])])])])):T("",!0),e("div",vt,[e("button",{type:"button",onClick:n[2]||(n[2]=M=>I.$emit("back")),class:"flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors"}," 上一步 "),e("button",{type:"button",onClick:l,disabled:!R.value||w.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold"},[w.value?(r(),u("div",gt)):T("",!0),g(" "+C(w.value?"验证中...":"完成授权"),1)],8,yt)])]))}},wt={key:0,class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},kt={class:"modal-content w-full max-w-md p-6 mx-auto"},ht={class:"flex items-start gap-4 mb-6"},$t={class:"flex-1"},Tt={class:"text-lg font-bold text-gray-900 mb-2"},Ct={class:"text-gray-600 text-sm leading-relaxed whitespace-pre-line"},At={class:"flex gap-3"},Ut={__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(U){return(V,i)=>(r(),N(me,{to:"body"},[U.show?(r(),u("div",wt,[e("div",kt,[e("div",ht,[i[2]||(i[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",$t,[e("h3",Tt,C(U.title),1),e("p",Ct,C(U.message),1)])]),e("div",At,[e("button",{onClick:i[0]||(i[0]=x=>V.$emit("cancel")),class:"flex-1 px-4 py-2.5 bg-gray-100 text-gray-700 rounded-xl font-medium hover:bg-gray-200 transition-colors"},C(U.cancelText),1),e("button",{onClick:i[1]||(i[1]=x=>V.$emit("confirm")),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"},C(U.confirmText),1)])])])):T("",!0)]))}},jt={key:0,class:"fixed inset-0 modal z-50 flex items-center justify-center p-4"},St={class:"modal-content w-full max-w-2xl p-8 mx-auto max-h-[90vh] overflow-y-auto custom-scrollbar"},_t={class:"flex items-center justify-between mb-6"},Vt={class:"flex items-center gap-3"},Gt={class:"text-xl font-bold text-gray-900"},It={key:0,class:"flex items-center justify-center mb-8"},Rt={class:"flex items-center space-x-4"},Mt={class:"flex items-center"},Pt={class:"flex items-center"},zt={key:1},Et={class:"space-y-6"},Dt={key:0},Lt={class:"flex gap-4"},Wt={class:"flex items-center cursor-pointer"},qt={class:"flex items-center cursor-pointer"},Kt={key:1},Ot={class:"flex gap-4"},Bt={class:"flex items-center cursor-pointer"},Nt={class:"flex items-center cursor-pointer"},Ht={class:"flex gap-4"},Ft={class:"flex items-center cursor-pointer"},Yt={class:"flex items-center cursor-pointer"},Qt={key:2},Xt={key:3,class:"space-y-4 bg-blue-50 p-4 rounded-lg border border-blue-200"},Zt={class:"flex items-start gap-3 mb-4"},Jt={key:0,class:"text-sm text-blue-800 mb-2"},es={key:1,class:"text-sm text-blue-800 mb-2"},ts={class:"bg-white/80 rounded-lg p-3 mt-2 mb-2 border border-blue-300"},ss={key:0,class:"text-xs text-blue-800"},ls={key:1,class:"text-xs text-blue-800"},os={class:"flex gap-3 pt-4"},as=["disabled"],ns=["disabled"],rs={key:0,class:"loading-spinner mr-2"},is={key:3,class:"space-y-6"},us={class:"flex gap-4"},ds={class:"flex items-center cursor-pointer"},cs={class:"flex items-center cursor-pointer"},ms={key:0},ps={class:"bg-amber-50 p-4 rounded-lg border border-amber-200"},fs={class:"space-y-4"},xs={class:"flex gap-3 pt-4"},vs=["disabled"],ys={key:0,class:"loading-spinner mr-2"},de={__name:"AccountForm",props:{account:{type:Object,default:null}},emits:["close","success"],setup(U,{emit:V}){var q,p,o,s,a,k;const i=U,x=V,m=pe(),{showConfirmModal:y,confirmOptions:w,showConfirm:v,handleConfirm:c,handleCancel:$}=he(),R=B(()=>!!i.account),z=b(!0),j=b(1),S=b(!1),l=b({platform:((q=i.account)==null?void 0:q.platform)||"claude",addType:"oauth",name:((p=i.account)==null?void 0:p.name)||"",description:((o=i.account)==null?void 0:o.description)||"",accountType:((s=i.account)==null?void 0:s.accountType)||"shared",projectId:((a=i.account)==null?void 0:a.projectId)||"",accessToken:"",refreshToken:"",proxy:((k=i.account)==null?void 0:k.proxy)||{enabled:!1,type:"socks5",host:"",port:"",username:"",password:""}}),I=B(()=>l.value.name&&l.value.platform),n=B(()=>l.value.addType==="manual"?l.value.name&&l.value.accessToken:l.value.name),M=async()=>{if(!I.value){(!l.value.name||l.value.name.trim()==="")&&A("请填写账户名称","error");return}l.value.platform==="gemini"&&j.value===1&&l.value.addType==="oauth"&&(!l.value.projectId||l.value.projectId.trim()==="")&&!await v("项目编号未填写",`您尚未填写项目编号。
如果您的Google账号绑定了Google Cloud或被识别为Workspace账号需要提供项目编号。
如果您使用的是普通个人账号,可以继续不填写。`,"继续","返回填写")||(j.value=2)},H=async f=>{S.value=!0;try{const t={name:l.value.name,description:l.value.description,accountType:l.value.accountType,accessToken:f.access_token,refreshToken:f.refresh_token,scopes:f.scopes||[],proxy:l.value.proxy.enabled?l.value.proxy:null};l.value.platform==="gemini"&&l.value.projectId&&(t.projectId=l.value.projectId);let d;l.value.platform==="claude"?d=await m.createClaudeAccount(t):d=await m.createGeminiAccount(t),A("账户创建成功","success"),x("success",d)}catch(t){A(t.message||"账户创建失败","error")}finally{S.value=!1}},F=async()=>{if(!n.value){!l.value.name||l.value.name.trim()===""?A("请填写账户名称","error"):(!l.value.accessToken||l.value.accessToken.trim()==="")&&A("请填写 Access Token","error");return}S.value=!0;try{const f={name:l.value.name,description:l.value.description,accountType:l.value.accountType,accessToken:l.value.accessToken,refreshToken:l.value.refreshToken||void 0,proxy:l.value.proxy.enabled?l.value.proxy:null};l.value.platform==="gemini"&&l.value.projectId&&(f.projectId=l.value.projectId);let t;l.value.platform==="claude"?t=await m.createClaudeAccount(f):t=await m.createGeminiAccount(f),A("账户创建成功","success"),x("success",t)}catch(f){A(f.message||"账户创建失败","error")}finally{S.value=!1}},Y=async()=>{if(!(l.value.platform==="gemini"&&(!l.value.projectId||l.value.projectId.trim()==="")&&!await v("项目编号未填写",`您尚未填写项目编号。
如果您的Google账号绑定了Google Cloud或被识别为Workspace账号需要提供项目编号。
如果您使用的是普通个人账号,可以继续不填写。`,"继续保存","返回填写"))){S.value=!0;try{const f={name:l.value.name,description:l.value.description,accountType:l.value.accountType,proxy:l.value.proxy.enabled?l.value.proxy:null};l.value.accessToken&&(f.accessToken=l.value.accessToken),l.value.refreshToken&&(f.refreshToken=l.value.refreshToken),i.account.platform==="gemini"&&l.value.projectId&&(f.projectId=l.value.projectId),i.account.platform==="claude"?await m.updateClaudeAccount(i.account.id,f):await m.updateGeminiAccount(i.account.id,f),x("success")}catch(f){A(f.message||"账户更新失败","error")}finally{S.value=!1}}};return K(()=>i.account,f=>{f&&(l.value={platform:f.platform,addType:"oauth",name:f.name,description:f.description||"",accountType:f.accountType||"shared",projectId:f.projectId||"",accessToken:"",refreshToken:"",proxy:f.proxy||{enabled:!1,type:"socks5",host:"",port:"",username:"",password:""}})},{immediate:!0}),(f,t)=>(r(),N(me,{to:"body"},[z.value?(r(),u("div",jt,[e("div",St,[e("div",_t,[e("div",Vt,[t[24]||(t[24]=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",Gt,C(R.value?"编辑账户":"添加账户"),1)]),e("button",{onClick:t[0]||(t[0]=d=>f.$emit("close")),class:"text-gray-400 hover:text-gray-600 transition-colors"},t[25]||(t[25]=[e("i",{class:"fas fa-times text-xl"},null,-1)]))]),!R.value&&l.value.addType==="oauth"?(r(),u("div",It,[e("div",Rt,[e("div",Mt,[e("div",{class:P(["w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold",j.value>=1?"bg-blue-500 text-white":"bg-gray-200 text-gray-500"])}," 1 ",2),t[26]||(t[26]=e("span",{class:"ml-2 text-sm font-medium text-gray-700"},"基本信息",-1))]),t[28]||(t[28]=e("div",{class:"w-8 h-0.5 bg-gray-300"},null,-1)),e("div",Pt,[e("div",{class:P(["w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold",j.value>=2?"bg-blue-500 text-white":"bg-gray-200 text-gray-500"])}," 2 ",2),t[27]||(t[27]=e("span",{class:"ml-2 text-sm font-medium text-gray-700"},"授权认证",-1))])])])):T("",!0),j.value===1&&!R.value?(r(),u("div",zt,[e("div",Et,[R.value?T("",!0):(r(),u("div",Dt,[t[31]||(t[31]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"平台",-1)),e("div",Lt,[e("label",Wt,[h(e("input",{type:"radio","onUpdate:modelValue":t[1]||(t[1]=d=>l.value.platform=d),value:"claude",class:"mr-2"},null,512),[[D,l.value.platform]]),t[29]||(t[29]=e("span",{class:"text-sm text-gray-700"},"Claude",-1))]),e("label",qt,[h(e("input",{type:"radio","onUpdate:modelValue":t[2]||(t[2]=d=>l.value.platform=d),value:"gemini",class:"mr-2"},null,512),[[D,l.value.platform]]),t[30]||(t[30]=e("span",{class:"text-sm text-gray-700"},"Gemini",-1))])])])),R.value?T("",!0):(r(),u("div",Kt,[t[34]||(t[34]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"添加方式",-1)),e("div",Ot,[e("label",Bt,[h(e("input",{type:"radio","onUpdate:modelValue":t[3]||(t[3]=d=>l.value.addType=d),value:"oauth",class:"mr-2"},null,512),[[D,l.value.addType]]),t[32]||(t[32]=e("span",{class:"text-sm text-gray-700"},"OAuth 授权 (推荐)",-1))]),e("label",Nt,[h(e("input",{type:"radio","onUpdate:modelValue":t[4]||(t[4]=d=>l.value.addType=d),value:"manual",class:"mr-2"},null,512),[[D,l.value.addType]]),t[33]||(t[33]=e("span",{class:"text-sm text-gray-700"},"手动输入 Access Token",-1))])])])),e("div",null,[t[35]||(t[35]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"账户名称",-1)),h(e("input",{"onUpdate:modelValue":t[5]||(t[5]=d=>l.value.name=d),type:"text",required:"",class:"form-input w-full",placeholder:"为账户设置一个易识别的名称"},null,512),[[G,l.value.name]])]),e("div",null,[t[36]||(t[36]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"描述 (可选)",-1)),h(e("textarea",{"onUpdate:modelValue":t[6]||(t[6]=d=>l.value.description=d),rows:"3",class:"form-input w-full resize-none",placeholder:"账户用途说明..."},null,512),[[G,l.value.description]])]),e("div",null,[t[39]||(t[39]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"账户类型",-1)),e("div",Ht,[e("label",Ft,[h(e("input",{type:"radio","onUpdate:modelValue":t[7]||(t[7]=d=>l.value.accountType=d),value:"shared",class:"mr-2"},null,512),[[D,l.value.accountType]]),t[37]||(t[37]=e("span",{class:"text-sm text-gray-700"},"共享账户",-1))]),e("label",Yt,[h(e("input",{type:"radio","onUpdate:modelValue":t[8]||(t[8]=d=>l.value.accountType=d),value:"dedicated",class:"mr-2"},null,512),[[D,l.value.accountType]]),t[38]||(t[38]=e("span",{class:"text-sm text-gray-700"},"专属账户",-1))])]),t[40]||(t[40]=e("p",{class:"text-xs text-gray-500 mt-2"}," 共享账户供所有API Key使用专属账户仅供特定API Key使用 ",-1))]),l.value.platform==="gemini"?(r(),u("div",Qt,[t[41]||(t[41]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"项目编号 (可选)",-1)),h(e("input",{"onUpdate:modelValue":t[9]||(t[9]=d=>l.value.projectId=d),type:"text",class:"form-input w-full",placeholder:"例如123456789012纯数字"},null,512),[[G,l.value.projectId]]),t[42]||(t[42]=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,[g("访问 "),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,[g("复制"),e("span",{class:"font-semibold text-red-600"},"项目编号Project Number"),g("通常是12位纯数字")]),e("li",{class:"text-red-600"},"⚠️ 注意不要复制项目IDProject ID要复制项目编号")])]),e("p",{class:"mt-2"},[e("strong",null,"提示:"),g("如果您的账号是普通个人账号(未绑定 Google Cloud请留空此字段。")])])])],-1))])):T("",!0),l.value.addType==="manual"?(r(),u("div",Xt,[e("div",Zt,[t[48]||(t[48]=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[46]||(t[46]=e("h5",{class:"font-semibold text-blue-900 mb-2"},"手动输入 Token",-1)),l.value.platform==="claude"?(r(),u("p",Jt," 请输入有效的 Claude Access Token。如果您有 Refresh Token建议也一并填写以支持自动刷新。 ")):l.value.platform==="gemini"?(r(),u("p",es," 请输入有效的 Gemini Access Token。如果您有 Refresh Token建议也一并填写以支持自动刷新。 ")):T("",!0),e("div",ts,[t[45]||(t[45]=e("p",{class:"text-sm text-blue-900 font-medium mb-1"},[e("i",{class:"fas fa-folder-open mr-1"}),g(" 获取 Access Token 的方法: ")],-1)),l.value.platform==="claude"?(r(),u("p",ss,t[43]||(t[43]=[g(" 请从已登录 Claude Code 的机器上获取 ",-1),e("code",{class:"bg-blue-100 px-1 py-0.5 rounded font-mono"},"~/.claude/.credentials.json",-1),g(" 文件中的凭证, 请勿使用 Claude 官网 API Keys 页面的密钥。 ",-1)]))):l.value.platform==="gemini"?(r(),u("p",ls,t[44]||(t[44]=[g(" 请从已登录 Gemini CLI 的机器上获取 ",-1),e("code",{class:"bg-blue-100 px-1 py-0.5 rounded font-mono"},"~/.config/gemini/credentials.json",-1),g(" 文件中的凭证。 ",-1)]))):T("",!0)]),t[47]||(t[47]=e("p",{class:"text-xs text-blue-600"},"💡 如果未填写 Refresh TokenToken 过期后需要手动更新。",-1))])]),e("div",null,[t[49]||(t[49]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"Access Token *",-1)),h(e("textarea",{"onUpdate:modelValue":t[10]||(t[10]=d=>l.value.accessToken=d),rows:"4",required:"",class:"form-input w-full resize-none font-mono text-xs",placeholder:"请输入 Access Token..."},null,512),[[G,l.value.accessToken]])]),e("div",null,[t[50]||(t[50]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"Refresh Token (可选)",-1)),h(e("textarea",{"onUpdate:modelValue":t[11]||(t[11]=d=>l.value.refreshToken=d),rows:"4",class:"form-input w-full resize-none font-mono text-xs",placeholder:"请输入 Refresh Token..."},null,512),[[G,l.value.refreshToken]])])])):T("",!0),X(ue,{modelValue:l.value.proxy,"onUpdate:modelValue":t[12]||(t[12]=d=>l.value.proxy=d)},null,8,["modelValue"]),e("div",os,[e("button",{type:"button",onClick:t[13]||(t[13]=d=>f.$emit("close")),class:"flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors"}," 取消 "),l.value.addType==="oauth"?(r(),u("button",{key:0,type:"button",onClick:M,disabled:!I.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold"}," 下一步 ",8,as)):(r(),u("button",{key:1,type:"button",onClick:F,disabled:S.value||!n.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold"},[S.value?(r(),u("div",rs)):T("",!0),g(" "+C(S.value?"创建中...":"创建"),1)],8,ns))])])])):T("",!0),j.value===2&&l.value.addType==="oauth"?(r(),N(bt,{key:2,platform:l.value.platform,proxy:l.value.proxy,onSuccess:H,onBack:t[14]||(t[14]=d=>j.value=1)},null,8,["platform","proxy"])):T("",!0),R.value?(r(),u("div",is,[e("div",null,[t[51]||(t[51]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"账户名称",-1)),h(e("input",{"onUpdate:modelValue":t[15]||(t[15]=d=>l.value.name=d),type:"text",required:"",class:"form-input w-full",placeholder:"为账户设置一个易识别的名称"},null,512),[[G,l.value.name]])]),e("div",null,[t[52]||(t[52]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"描述 (可选)",-1)),h(e("textarea",{"onUpdate:modelValue":t[16]||(t[16]=d=>l.value.description=d),rows:"3",class:"form-input w-full resize-none",placeholder:"账户用途说明..."},null,512),[[G,l.value.description]])]),e("div",null,[t[55]||(t[55]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"账户类型",-1)),e("div",us,[e("label",ds,[h(e("input",{type:"radio","onUpdate:modelValue":t[17]||(t[17]=d=>l.value.accountType=d),value:"shared",class:"mr-2"},null,512),[[D,l.value.accountType]]),t[53]||(t[53]=e("span",{class:"text-sm text-gray-700"},"共享账户",-1))]),e("label",cs,[h(e("input",{type:"radio","onUpdate:modelValue":t[18]||(t[18]=d=>l.value.accountType=d),value:"dedicated",class:"mr-2"},null,512),[[D,l.value.accountType]]),t[54]||(t[54]=e("span",{class:"text-sm text-gray-700"},"专属账户",-1))])]),t[56]||(t[56]=e("p",{class:"text-xs text-gray-500 mt-2"}," 共享账户供所有API Key使用专属账户仅供特定API Key使用 ",-1))]),l.value.platform==="gemini"?(r(),u("div",ms,[t[57]||(t[57]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"项目编号 (可选)",-1)),h(e("input",{"onUpdate:modelValue":t[19]||(t[19]=d=>l.value.projectId=d),type:"text",class:"form-input w-full",placeholder:"例如123456789012纯数字"},null,512),[[G,l.value.projectId]]),t[58]||(t[58]=e("p",{class:"text-xs text-gray-500 mt-2"}," Google Cloud/Workspace 账号可能需要提供项目编号 ",-1))])):T("",!0),e("div",ps,[t[61]||(t[61]=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",fs,[e("div",null,[t[59]||(t[59]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"新的 Access Token",-1)),h(e("textarea",{"onUpdate:modelValue":t[20]||(t[20]=d=>l.value.accessToken=d),rows:"4",class:"form-input w-full resize-none font-mono text-xs",placeholder:"留空表示不更新..."},null,512),[[G,l.value.accessToken]])]),e("div",null,[t[60]||(t[60]=e("label",{class:"block text-sm font-semibold text-gray-700 mb-3"},"新的 Refresh Token",-1)),h(e("textarea",{"onUpdate:modelValue":t[21]||(t[21]=d=>l.value.refreshToken=d),rows:"4",class:"form-input w-full resize-none font-mono text-xs",placeholder:"留空表示不更新..."},null,512),[[G,l.value.refreshToken]])])])]),X(ue,{modelValue:l.value.proxy,"onUpdate:modelValue":t[22]||(t[22]=d=>l.value.proxy=d)},null,8,["modelValue"]),e("div",xs,[e("button",{type:"button",onClick:t[23]||(t[23]=d=>f.$emit("close")),class:"flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors"}," 取消 "),e("button",{type:"button",onClick:Y,disabled:S.value,class:"btn btn-primary flex-1 py-3 px-6 font-semibold"},[S.value?(r(),u("div",ys)):T("",!0),g(" "+C(S.value?"更新中...":"更新"),1)],8,vs)])])):T("",!0)])])):T("",!0),X(Ut,{show:L(y),title:L(w).title,message:L(w).message,"confirm-text":L(w).confirmText,"cancel-text":L(w).cancelText,onConfirm:L(c),onCancel:L($)},null,8,["show","title","message","confirm-text","cancel-text","onConfirm","onCancel"])]))}},gs={class:"accounts-container"},bs={class:"card p-6"},ws={class:"flex flex-col md:flex-row justify-between items-center gap-4 mb-6"},ks={class:"flex gap-2"},hs={key:0,class:"text-center py-12"},$s={key:1,class:"text-center py-12"},Ts={key:2,class:"table-container"},Cs={class:"min-w-full"},As={class:"bg-gray-50/80 backdrop-blur-sm"},Us={key:1,class:"fas fa-sort ml-1 text-gray-400"},js={key:1,class:"fas fa-sort ml-1 text-gray-400"},Ss={key:1,class:"fas fa-sort ml-1 text-gray-400"},_s={key:1,class:"fas fa-sort ml-1 text-gray-400"},Vs={class:"divide-y divide-gray-200/50"},Gs={class:"px-6 py-4 whitespace-nowrap"},Is={class:"flex items-center"},Rs={class:"flex items-center gap-2"},Ms={class:"text-sm font-semibold text-gray-900"},Ps={key:0,class:"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800"},zs={key:1,class:"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800"},Es={class:"text-xs text-gray-500"},Ds={class:"px-6 py-4 whitespace-nowrap"},Ls={key:0,class:"inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-800"},Ws={key:1,class:"inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-indigo-100 text-indigo-800"},qs={class:"px-6 py-4 whitespace-nowrap"},Ks={key:0,class:"inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-blue-100 text-blue-800"},Os={key:1,class:"inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-orange-100 text-orange-800"},Bs={class:"px-6 py-4 whitespace-nowrap"},Ns={class:"flex flex-col gap-1"},Hs={key:0,class:"inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-800"},Fs={key:1,class:"text-xs text-gray-500"},Ys={class:"px-6 py-4 whitespace-nowrap text-sm text-gray-600"},Qs={key:0,class:"text-xs bg-blue-50 px-2 py-1 rounded"},Xs={key:1,class:"text-gray-400"},Zs={class:"px-6 py-4 whitespace-nowrap text-sm"},Js={key:0,class:"space-y-1"},el={class:"flex items-center gap-2"},tl={class:"text-sm font-medium text-gray-900"},sl={class:"flex items-center gap-2"},ll={class:"text-xs text-gray-600"},ol={key:0,class:"text-xs text-gray-500"},al={key:1,class:"text-gray-400 text-xs"},nl={class:"px-6 py-4 whitespace-nowrap"},rl={key:0,class:"space-y-2"},il={class:"flex items-center gap-2"},ul={class:"w-24 bg-gray-200 rounded-full h-2"},dl={class:"text-xs text-gray-700 font-medium min-w-[32px]"},cl={class:"text-xs text-gray-600"},ml={key:0,class:"text-indigo-600 font-medium"},pl={key:1,class:"text-gray-400 text-sm"},fl={key:2,class:"text-gray-400 text-sm"},xl={class:"px-6 py-4 whitespace-nowrap text-sm text-gray-600"},vl={class:"px-6 py-4 whitespace-nowrap text-sm font-medium"},yl={class:"flex items-center gap-2"},gl=["onClick","disabled","title"],bl=["onClick"],wl=["onClick"],kl={__name:"AccountsView",setup(U){const V=b([]),i=b(!1),x=b("name"),m=b(""),y=b("asc"),w=b([]),v=b(!1),c=b(!1),$=b(null),R=B(()=>m.value?[...V.value].sort((s,a)=>{var t,d,E,Z,J,ee,te,se,le,oe,ae,ne;let k=s[m.value],f=a[m.value];return m.value==="dailyTokens"?(k=((d=(t=s.usage)==null?void 0:t.daily)==null?void 0:d.allTokens)||0,f=((Z=(E=a.usage)==null?void 0:E.daily)==null?void 0:Z.allTokens)||0):m.value==="dailyRequests"?(k=((ee=(J=s.usage)==null?void 0:J.daily)==null?void 0:ee.requests)||0,f=((se=(te=a.usage)==null?void 0:te.daily)==null?void 0:se.requests)||0):m.value==="totalTokens"&&(k=((oe=(le=s.usage)==null?void 0:le.total)==null?void 0:oe.allTokens)||0,f=((ne=(ae=a.usage)==null?void 0:ae.total)==null?void 0:ne.allTokens)||0),m.value==="lastUsed"&&(k=s.lastUsedAt?new Date(s.lastUsedAt).getTime():0,f=a.lastUsedAt?new Date(a.lastUsedAt).getTime():0),m.value==="status"&&(k=s.isActive?1:0,f=a.isActive?1:0),k<f?y.value==="asc"?-1:1:k>f?y.value==="asc"?1:-1:0}):V.value),z=async()=>{i.value=!0;try{const[o,s,a]=await Promise.all([_.get("/admin/claude-accounts"),_.get("/admin/gemini-accounts"),_.get("/admin/api-keys")]);a.success&&(w.value=a.data||[]);const k=[];if(o.success){const f=(o.data||[]).map(t=>{const d=w.value.filter(E=>E.claudeAccountId===t.id).length;return{...t,platform:"claude",boundApiKeysCount:d}});k.push(...f)}if(s.success){const f=(s.data||[]).map(t=>{const d=w.value.filter(E=>E.geminiAccountId===t.id).length;return{...t,platform:"gemini",boundApiKeysCount:d}});k.push(...f)}V.value=k}catch{A("加载账户失败","error")}finally{i.value=!1}},j=o=>{o&&(m.value===o?y.value=y.value==="asc"?"desc":"asc":(m.value=o,y.value="asc"))},S=o=>{if(o==null)return"0";const s=Number(o);return s>=1e6?Math.floor(s/1e6).toLocaleString()+"M":s.toLocaleString()},l=o=>{if(!o)return"从未使用";const s=new Date(o),k=new Date-s;return k<6e4?"刚刚":k<36e5?`${Math.floor(k/6e4)} 分钟前`:k<864e5?`${Math.floor(k/36e5)} 小时前`:k<6048e5?`${Math.floor(k/864e5)} 天前`:s.toLocaleDateString("zh-CN")},I=(o,s)=>{if(!o||!s)return"--";const a=new Date(o),k=new Date(s),f=a.getHours().toString().padStart(2,"0"),t=a.getMinutes().toString().padStart(2,"0"),d=k.getHours().toString().padStart(2,"0"),E=k.getMinutes().toString().padStart(2,"0");return`${f}:${t} - ${d}:${E}`},n=o=>{if(!o||o<=0)return"已结束";const s=Math.floor(o/60),a=o%60;return s>0?`${s}小时${a}分钟`:`${a}分钟`},M=()=>{v.value=!0},H=o=>{$.value=o,c.value=!0},F=async o=>{if(confirm(`确定要删除账户 "${o.name}" 吗?此操作不可恢复。`))try{const s=o.platform==="claude"?`/admin/claude-accounts/${o.id}`:`/admin/gemini-accounts/${o.id}`,a=await _.delete(s);a.success?(A("账户已删除","success"),z()):A(a.message||"删除失败","error")}catch{A("删除失败","error")}},Y=async o=>{if(!o.isRefreshing)try{o.isRefreshing=!0;const s=await _.post(`/admin/claude-accounts/${o.id}/refresh`);s.success?(A("Token刷新成功","success"),z()):A(s.message||"Token刷新失败","error")}catch{A("Token刷新失败","error")}finally{o.isRefreshing=!1}},q=()=>{v.value=!1,A("账户创建成功","success"),z()},p=()=>{c.value=!1,A("账户更新成功","success"),z()};return K(x,o=>{const s={name:"name",dailyTokens:"dailyTokens",dailyRequests:"dailyRequests",totalTokens:"totalTokens",lastUsed:"lastUsed"};s[o]&&j(s[o])}),ve(()=>{z()}),(o,s)=>(r(),u("div",gs,[e("div",bs,[e("div",ws,[s[10]||(s[10]=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",ks,[h(e("select",{"onUpdate:modelValue":s[0]||(s[0]=a=>x.value=a),onChange:s[1]||(s[1]=a=>j()),class:"form-input px-3 py-2 text-sm"},s[8]||(s[8]=[O('<option value="name" data-v-1665099c>按名称排序</option><option value="dailyTokens" data-v-1665099c>按今日Token排序</option><option value="dailyRequests" data-v-1665099c>按今日请求数排序</option><option value="totalTokens" data-v-1665099c>按总Token排序</option><option value="lastUsed" data-v-1665099c>按最后使用排序</option>',5)]),544),[[ce,x.value]]),e("button",{onClick:ye(M,["stop"]),class:"btn btn-success px-6 py-3 flex items-center gap-2"},s[9]||(s[9]=[e("i",{class:"fas fa-plus"},null,-1),g("添加账户 ",-1)]))])]),i.value?(r(),u("div",hs,s[11]||(s[11]=[e("div",{class:"loading-spinner mx-auto mb-4"},null,-1),e("p",{class:"text-gray-500"},"正在加载账户...",-1)]))):R.value.length===0?(r(),u("div",$s,s[12]||(s[12]=[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)]))):(r(),u("div",Ts,[e("table",Cs,[e("thead",As,[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:s[2]||(s[2]=a=>j("name"))},[s[13]||(s[13]=g(" 名称 ",-1)),m.value==="name"?(r(),u("i",{key:0,class:P(["fas",y.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),u("i",Us))]),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:s[3]||(s[3]=a=>j("platform"))},[s[14]||(s[14]=g(" 平台 ",-1)),m.value==="platform"?(r(),u("i",{key:0,class:P(["fas",y.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),u("i",js))]),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:s[4]||(s[4]=a=>j("accountType"))},[s[15]||(s[15]=g(" 类型 ",-1)),m.value==="accountType"?(r(),u("i",{key:0,class:P(["fas",y.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),u("i",Ss))]),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:s[5]||(s[5]=a=>j("status"))},[s[16]||(s[16]=g(" 状态 ",-1)),m.value==="status"?(r(),u("i",{key:0,class:P(["fas",y.value==="asc"?"fa-sort-up":"fa-sort-down","ml-1"])},null,2)):(r(),u("i",_s))]),s[17]||(s[17]=e("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider"},"代理",-1)),s[18]||(s[18]=e("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider"},"今日使用",-1)),s[19]||(s[19]=e("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider"},"会话窗口",-1)),s[20]||(s[20]=e("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider"},"最后使用",-1)),s[21]||(s[21]=e("th",{class:"px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider"},"操作",-1))])]),e("tbody",Vs,[(r(!0),u(ge,null,be(R.value,a=>(r(),u("tr",{key:a.id,class:"table-row"},[e("td",Gs,[e("div",Is,[s[24]||(s[24]=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",Rs,[e("div",Ms,C(a.name),1),a.accountType==="dedicated"?(r(),u("span",Ps,s[22]||(s[22]=[e("i",{class:"fas fa-lock mr-1"},null,-1),g("专属 ",-1)]))):(r(),u("span",zs,s[23]||(s[23]=[e("i",{class:"fas fa-share-alt mr-1"},null,-1),g("共享 ",-1)])))]),e("div",Es,C(a.id),1)])])]),e("td",Ds,[a.platform==="gemini"?(r(),u("span",Ls,s[25]||(s[25]=[e("i",{class:"fas fa-robot mr-1"},null,-1),g("Gemini ",-1)]))):(r(),u("span",Ws,s[26]||(s[26]=[e("i",{class:"fas fa-brain mr-1"},null,-1),g("Claude ",-1)])))]),e("td",qs,[a.scopes&&a.scopes.length>0?(r(),u("span",Ks,s[27]||(s[27]=[e("i",{class:"fas fa-lock mr-1"},null,-1),g("OAuth ",-1)]))):(r(),u("span",Os,s[28]||(s[28]=[e("i",{class:"fas fa-key mr-1"},null,-1),g("传统 ",-1)])))]),e("td",Bs,[e("div",Ns,[e("span",{class:P(["inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold",a.isActive?"bg-green-100 text-green-800":"bg-red-100 text-red-800"])},[e("div",{class:P(["w-2 h-2 rounded-full mr-2",a.isActive?"bg-green-500":"bg-red-500"])},null,2),g(" "+C(a.isActive?"正常":"异常"),1)],2),a.rateLimitStatus&&a.rateLimitStatus.isRateLimited?(r(),u("span",Hs,[s[29]||(s[29]=e("i",{class:"fas fa-exclamation-triangle mr-1"},null,-1)),g(" 限流中 ("+C(a.rateLimitStatus.minutesRemaining)+"分钟) ",1)])):T("",!0),a.accountType==="dedicated"?(r(),u("span",Fs," 绑定: "+C(a.boundApiKeysCount||0)+" 个API Key ",1)):T("",!0)])]),e("td",Ys,[a.proxy?(r(),u("div",Qs,C(a.proxy.type)+"://"+C(a.proxy.host)+":"+C(a.proxy.port),1)):(r(),u("div",Xs,"无代理"))]),e("td",Zs,[a.usage&&a.usage.daily?(r(),u("div",Js,[e("div",el,[s[30]||(s[30]=e("div",{class:"w-2 h-2 bg-green-500 rounded-full"},null,-1)),e("span",tl,C(a.usage.daily.requests||0)+" 次",1)]),e("div",sl,[s[31]||(s[31]=e("div",{class:"w-2 h-2 bg-blue-500 rounded-full"},null,-1)),e("span",ll,C(S(a.usage.daily.allTokens||0))+" tokens",1)]),a.usage.averages&&a.usage.averages.rpm>0?(r(),u("div",ol," 平均 "+C(a.usage.averages.rpm.toFixed(2))+" RPM ",1)):T("",!0)])):(r(),u("div",al,"暂无数据"))]),e("td",nl,[a.platform==="claude"&&a.sessionWindow&&a.sessionWindow.hasActiveWindow?(r(),u("div",rl,[e("div",il,[e("div",ul,[e("div",{class:"bg-gradient-to-r from-blue-500 to-indigo-600 h-2 rounded-full transition-all duration-300",style:we({width:a.sessionWindow.progress+"%"})},null,4)]),e("span",dl,C(a.sessionWindow.progress)+"% ",1)]),e("div",cl,[e("div",null,C(I(a.sessionWindow.windowStart,a.sessionWindow.windowEnd)),1),a.sessionWindow.remainingTime>0?(r(),u("div",ml," 剩余 "+C(n(a.sessionWindow.remainingTime)),1)):T("",!0)])])):a.platform==="claude"?(r(),u("div",pl,s[32]||(s[32]=[e("i",{class:"fas fa-minus"},null,-1)]))):(r(),u("div",fl,s[33]||(s[33]=[e("span",{class:"text-xs"},"N/A",-1)])))]),e("td",xl,C(l(a.lastUsedAt)),1),e("td",vl,[e("div",yl,[a.platform==="claude"&&a.scopes?(r(),u("button",{key:0,onClick:k=>Y(a),disabled:a.isRefreshing,class:P(["px-3 py-1.5 rounded-lg text-xs font-medium transition-colors",a.isRefreshing?"bg-gray-100 text-gray-400 cursor-not-allowed":"bg-blue-100 text-blue-700 hover:bg-blue-200"]),title:a.isRefreshing?"刷新中...":"刷新Token"},[e("i",{class:P(["fas fa-sync-alt",a.isRefreshing?"animate-spin":""])},null,2)],10,gl)):T("",!0),e("button",{onClick:k=>H(a),class:"px-3 py-1.5 bg-blue-100 text-blue-700 rounded-lg text-xs font-medium hover:bg-blue-200 transition-colors"},s[34]||(s[34]=[e("i",{class:"fas fa-edit"},null,-1)]),8,bl),e("button",{onClick:k=>F(a),class:"px-3 py-1.5 bg-red-100 text-red-700 rounded-lg text-xs font-medium hover:bg-red-200 transition-colors"},s[35]||(s[35]=[e("i",{class:"fas fa-trash"},null,-1)]),8,wl)])])]))),128))])])]))]),v.value?(r(),N(de,{key:0,onClose:s[6]||(s[6]=a=>v.value=!1),onSuccess:q})):T("",!0),c.value?(r(),N(de,{key:1,account:$.value,onClose:s[7]||(s[7]=a=>c.value=!1),onSuccess:p},null,8,["account"])):T("",!0)]))}},Ul=ke(kl,[["__scopeId","data-v-1665099c"]]);export{Ul as default};