astrion-website/demo/static/dist/assets/adminApi.js

2 lines
12 KiB
JavaScript

import{d as ge,o as _e,w as ne,a as ke,c as d,u as B,b as Ae,e as E,f as t,t as n,g as O,v as ye,h as ae,i as se,F as G,r as K,j as m,k as D,l as i,m as r,n as oe,p as $e,q as we}from"./index.js";import{S as Ce,u as Te}from"./SecondaryGate.js";import{_ as Fe}from"./_plugin-vue_export-helper.js";const Se={class:"api-page"},Ne={class:"api-header"},Re={class:"muted"},Be={class:"header-actions"},Ee=["disabled"],Ie={class:"panel"},Me={class:"metrics-grid"},qe={class:"metric-card"},Ue={class:"metric-card"},je={class:"metric-card"},Ve={class:"muted"},De={class:"metric-card"},Le={class:"muted"},Pe={class:"panel"},ze={class:"section-head"},Oe={class:"create-form"},Ge=["placeholder"],Ke=["placeholder"],Ze=["disabled"],Je={class:"table-wrapper"},He={key:0},Qe={colspan:"10"},We={key:0,class:"status-badge online"},Xe={key:1,class:"status-badge offline"},Ye={class:"token-cell"},xe={class:"token-text"},et=["onClick","disabled"],tt=["onClick","disabled"],nt=["onClick","disabled"],at={key:0,class:"error-text"},st={class:"panel grid"},ot={class:"section-head"},lt={class:"muted"},it={class:"table-wrapper small scrollable"},rt={key:0},dt={colspan:"6"},ut={class:"section-head"},ct={class:"muted"},mt={class:"upload-feed scrollable"},pt={key:0,class:"upload-item"},ht={class:"muted small"},vt={class:"muted small"},ft=ge({__name:"ApiAdminApp",setup(gt){const{verified:p,configured:ie,loading:re,error:de,check:Z,verify:ue}=Te(),I=m(!1),M=m(!0);let h;const _=m(null),k=m([]),c=m({}),q=m(""),L=m(""),U=m(!1),v=m({username:"",note:""}),f=m(""),b=D(()=>{var e;return((e=_.value)==null?void 0:e.overview)||{}}),J=D(()=>{var e;return((e=_.value)==null?void 0:e.uploads)||{}}),H=D(()=>{var a;const e=((a=_.value)==null?void 0:a.containers)||{};return Object.keys(e).map(l=>({key:l,...e[l]||{}}))}),ce=D(()=>k.value.reduce((e,a)=>e+(a.usage&&a.usage.total_requests?a.usage.total_requests:0),0)),g=e=>{const a=Number(e||0);return Number.isFinite(a)?a.toLocaleString("zh-CN"):"0"},A=e=>{const a=Number(e||0);if(!a)return"0B";const l=["B","KB","MB","GB","TB"];let o=a,u=0;for(;o>=1024&&u<l.length-1;)o/=1024,u+=1;return`${o.toFixed(1)}${l[u]}`},me=e=>{if(!e)return"—";try{return new Date(e).toLocaleString()}catch{return e}},P=e=>{if(!e)return"—";const a=new Date(e).getTime();if(!Number.isFinite(a))return"—";const l=Date.now()-a,o=Math.floor(l/6e4);if(o<1)return i("common.justNow");if(o<60)return i("common.minutesAgo",{n:o});const u=Math.floor(o/60);if(u<24)return i("common.hoursAgo",{n:u});const V=Math.floor(u/24);return i("common.daysAgo",{n:V})},Q=e=>{if(e==null)return"—";const a=Number(e);return Number.isFinite(a)?`${a.toFixed(1)}%`:"—"},pe=async()=>{if(p.value){I.value=!0;try{const e=await fetch("/api/admin/api-dashboard",{credentials:"same-origin"}),a=await e.json();if(!e.ok||!a.success)throw new Error(a.error||i("common.loadFailed"));_.value=a.data}catch(e){console.error(e)}finally{I.value=!1}}},z=async()=>{if(p.value)try{const e=await fetch("/api/admin/api-users",{credentials:"same-origin"}),a=await e.json();if(!e.ok||!a.success)throw new Error(a.error||i("common.loadFailed"));const l={};k.value=(a.data||[]).map(o=>({...o,usage:o.usage||{total_requests:0,endpoints:{},last_request_at:null},tokens:o.tokens||{total_tokens:0,input_tokens:0,output_tokens:0},storage:o.storage||{total_bytes:0}})),k.value.forEach(o=>{l[o.username]=c.value[o.username]||{token:"",visible:!1}}),c.value=l}catch(e){console.error(e)}},y=async()=>{await Promise.all([pe(),z()])},j=()=>{h&&(clearInterval(h),h=void 0),M.value&&p.value&&(h=window.setInterval(y,3e4))},he=async()=>{if(!p.value)return;f.value="";const e=v.value.username.trim().toLowerCase();if(!e){f.value=i("adminApi.usernameRequired");return}if(!/^[a-z0-9_-]{3,32}$/.test(e)){f.value=i("adminApi.usernameInvalid");return}U.value=!0;try{const l=await fetch("/api/admin/api-users",{method:"POST",credentials:"same-origin",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:e,note:v.value.note})}),o=await l.json();if(!l.ok||!o.success)throw new Error(o.error||i("adminApi.createFailed"));await z(),c.value[e]={token:o.data.token,visible:!0},v.value={username:"",note:""}}catch(l){f.value=l.message||i("adminApi.createFailed")}finally{U.value=!1}},ve=async e=>{if(p.value&&confirm(i("adminApi.deleteConfirm",{username:e}))){L.value=e;try{const a=await fetch(`/api/admin/api-users/${encodeURIComponent(e)}`,{method:"DELETE",credentials:"same-origin"}),l=await a.json();if(!a.ok||!l.success)throw new Error(l.error||i("adminApi.deleteFailed"));await z()}catch(a){alert(a.message||i("adminApi.deleteFailed"))}finally{L.value=""}}},W=async e=>{const a=c.value[e];if(a!=null&&a.visible){c.value[e]={...a||{},visible:!1};return}q.value=e;try{const l=await fetch(`/api/admin/api-users/${encodeURIComponent(e)}/token`,{credentials:"same-origin"}),o=await l.json();if(!l.ok||!o.success)throw new Error(o.error||i("adminApi.fetchFailed"));c.value[e]={token:o.data.token,visible:!0}}catch(l){alert(l.message||i("adminApi.fetchTokenFailed"))}finally{q.value=""}},fe=async e=>{var o;const a=c.value[e];a!=null&&a.token||await W(e);const l=(o=c.value[e])==null?void 0:o.token;if(l)try{await navigator.clipboard.writeText(l)}catch(u){console.error(u)}},be=async e=>{await ue(e),p.value&&(await y(),j())};return _e(async()=>{await Z(),p.value&&(await y(),j())}),ne(M,j),ne(p,e=>{e?(y(),j()):h&&(clearInterval(h),h=void 0)}),ke(()=>{h&&clearInterval(h)}),(e,a)=>{var l,o,u,V,X,Y,x,ee;return r(),d("div",Se,[B(p)?E("",!0):(r(),Ae(Ce,{key:0,configured:B(ie),loading:B(re),error:B(de),description:e.$t("adminApi.gateDescription"),onVerify:be,onRecheck:B(Z)},null,8,["configured","loading","error","description","onRecheck"])),t("header",Ne,[t("div",null,[t("h1",null,n(e.$t("adminApi.title")),1),t("p",null,n(e.$t("adminApi.subtitle")),1),t("small",Re,n(e.$t("adminApi.dataTime",{time:P((l=_.value)==null?void 0:l.generated_at)})),1)]),t("div",Be,[t("label",null,[O(t("input",{type:"checkbox","onUpdate:modelValue":a[0]||(a[0]=s=>M.value=s)},null,512),[[ye,M.value]]),ae(" "+n(e.$t("adminApi.autoRefresh")),1)]),t("button",{type:"button",disabled:I.value,onClick:y},n(I.value?e.$t("common.refreshing"):e.$t("adminApi.manualRefresh")),9,Ee)])]),t("section",Ie,[t("div",Me,[t("div",qe,[t("p",null,n(e.$t("adminApi.metricUsers")),1),t("strong",null,n(((o=b.value.totals)==null?void 0:o.users)||0),1)]),t("div",Ue,[t("p",null,n(e.$t("adminApi.metricTotalRequests")),1),t("strong",null,n(g(ce.value)),1)]),t("div",je,[t("p",null,n(e.$t("adminApi.metricTotalTokens")),1),t("strong",null,n(g(((u=b.value.token_totals)==null?void 0:u.total_tokens)||0)),1),t("span",Ve,n(e.$t("adminApi.tokenInOut",{input:g(((V=b.value.token_totals)==null?void 0:V.input_tokens)||0),output:g(((X=b.value.token_totals)==null?void 0:X.output_tokens)||0)})),1)]),t("div",De,[t("p",null,n(e.$t("adminApi.metricActiveContainers")),1),t("strong",null,n(((Y=b.value.totals)==null?void 0:Y.containers_active)||0),1),t("span",Le,n(e.$t("adminApi.availableSlots",{slots:((x=b.value.totals)==null?void 0:x.available_container_slots)??"—"})),1)])])]),t("section",Pe,[t("div",ze,[t("h2",null,n(e.$t("adminApi.accountManagement")),1),t("div",Oe,[O(t("input",{"onUpdate:modelValue":a[1]||(a[1]=s=>v.value.username=s),type:"text",placeholder:e.$t("adminApi.usernamePlaceholder")},null,8,Ge),[[se,v.value.username]]),O(t("input",{"onUpdate:modelValue":a[2]||(a[2]=s=>v.value.note=s),type:"text",placeholder:e.$t("adminApi.notePlaceholder")},null,8,Ke),[[se,v.value.note]]),t("button",{type:"button",disabled:U.value,onClick:he},n(U.value?e.$t("adminApi.creating"):e.$t("adminApi.createAccount")),9,Ze)])]),t("div",Je,[t("table",null,[t("thead",null,[t("tr",null,[t("th",null,n(e.$t("adminApi.tableUsername")),1),t("th",null,n(e.$t("adminApi.tableNote")),1),t("th",null,n(e.$t("adminApi.tableCreatedAt")),1),t("th",null,n(e.$t("adminApi.tableRequests")),1),t("th",null,n(e.$t("adminApi.tableLastCall")),1),t("th",null,n(e.$t("adminApi.tableTotalTokens")),1),t("th",null,n(e.$t("adminApi.tableStorage")),1),t("th",null,n(e.$t("adminApi.tableContainer")),1),t("th",null,n(e.$t("adminApi.tableToken")),1),t("th",null,n(e.$t("adminApi.tableActions")),1)])]),t("tbody",null,[k.value.length?E("",!0):(r(),d("tr",He,[t("td",Qe,n(e.$t("adminApi.emptyAccounts")),1)])),(r(!0),d(G,null,K(k.value,s=>{var $,w,C,T,F,S,N;return r(),d("tr",{key:s.username},[t("td",null,[t("strong",null,n(s.username),1)]),t("td",null,n(s.note||"—"),1),t("td",null,n(me(s.created_at)),1),t("td",null,n(g((($=s.usage)==null?void 0:$.total_requests)||0)),1),t("td",null,n(P((w=s.usage)==null?void 0:w.last_request_at)),1),t("td",null,n(g(((C=s.tokens)==null?void 0:C.total_tokens)||0)),1),t("td",null,n(A((T=s.storage)==null?void 0:T.total_bytes)),1),t("td",null,[(F=s.container)!=null&&F.running?(r(),d("span",We,n(e.$t("common.running")),1)):(r(),d("span",Xe,n(e.$t("common.notRunning")),1))]),t("td",Ye,[t("span",xe,n((S=c.value[s.username])!=null&&S.visible?((N=c.value[s.username])==null?void 0:N.token)||"—":"••••••••••"),1),t("button",{class:"icon-btn",onClick:R=>W(s.username),disabled:q.value===s.username},[...a[3]||(a[3]=[t("svg",{viewBox:"0 0 24 24",width:"18",height:"18","aria-hidden":"true"},[t("path",{d:"M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12Zm11 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z",fill:"none",stroke:"currentColor","stroke-width":"1.5"})],-1)])],8,et),t("button",{class:"icon-btn",onClick:R=>fe(s.username),disabled:q.value===s.username}," 📋 ",8,tt)]),t("td",null,[t("button",{class:"link danger",onClick:R=>ve(s.username),disabled:L.value===s.username},n(e.$t("common.delete")),9,nt)])])}),128))])])]),f.value?(r(),d("p",at,n(f.value),1)):E("",!0)]),t("section",st,[t("div",null,[t("div",ot,[t("h3",null,n(e.$t("adminApi.containerSection")),1),t("small",lt,n(e.$t("adminApi.realtimeFetch")),1)]),t("div",it,[t("table",null,[t("thead",null,[t("tr",null,[t("th",null,n(e.$t("adminApi.tableKey")),1),t("th",null,n(e.$t("adminApi.tableCpu")),1),t("th",null,n(e.$t("adminApi.tableMemPercent")),1),t("th",null,n(e.$t("adminApi.tableMemory")),1),t("th",null,n(e.$t("adminApi.tableNetIo")),1),t("th",null,n(e.$t("adminApi.tableStatus")),1)])]),t("tbody",null,[H.value.length?E("",!0):(r(),d("tr",rt,[t("td",dt,n(e.$t("adminApi.emptyContainers")),1)])),(r(!0),d(G,null,K(H.value,s=>{var $,w,C,T,F,S,N,R,te;return r(),d("tr",{key:s.key},[t("td",null,n(s.key),1),t("td",null,n(Q(($=s.stats)==null?void 0:$.cpu_percent)),1),t("td",null,n(Q((C=(w=s.stats)==null?void 0:w.memory)==null?void 0:C.percent)),1),t("td",null,n(A((F=(T=s.stats)==null?void 0:T.memory)==null?void 0:F.used_bytes)),1),t("td",null,n(A((N=(S=s.stats)==null?void 0:S.net_io)==null?void 0:N.rx_bytes))+" / "+n(A((te=(R=s.stats)==null?void 0:R.net_io)==null?void 0:te.tx_bytes)),1),t("td",null,[t("span",{class:oe(["status-badge",s.running?"online":"offline"])},n(s.running?e.$t("common.running"):e.$t("common.notRunning")),3)])])}),128))])])])]),t("div",null,[t("div",ut,[t("h3",null,n(e.$t("adminApi.uploadSection")),1),t("small",ct,n(e.$t("adminApi.uploadSourceNote")),1)]),t("ul",mt,[(ee=J.value.recent_events)!=null&&ee.length?E("",!0):(r(),d("li",pt,n(e.$t("adminApi.emptyRecords")),1)),(r(!0),d(G,null,K(J.value.recent_events||[],s=>(r(),d("li",{key:s.upload_id,class:"upload-item"},[t("div",null,[t("strong",null,n(s.original_name||e.$t("adminApi.unnamedFile")),1),t("div",ht,n(e.$t("adminApi.uploadMeta",{username:s.username,size:A(s.size),source:s.source||"unknown"})),1)]),t("div",vt,[ae(n(P(s.timestamp))+" ",1),t("span",{class:oe(["status-badge",s.accepted?"online":"danger"])},n(s.accepted?e.$t("adminApi.accepted"):e.$t("adminApi.blocked")),3)])]))),128))])])])])}}}),bt=Fe(ft,[["__scopeId","data-v-4f53a3c2"]]),le=$e(bt);we(le);le.mount("#admin-api-app");