ezllm 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +57 -0
- package/bin/ellm-proxy.js +3 -0
- package/dist/cli.js +27667 -0
- package/dist/package.json +1 -0
- package/dist/server.js +42403 -0
- package/dist/web-ui/assets/DashboardView-DwlQExQv.css +1 -0
- package/dist/web-ui/assets/DashboardView-fRDkGq0g.js +1 -0
- package/dist/web-ui/assets/LayoutView-CK_MaWN7.js +1 -0
- package/dist/web-ui/assets/LayoutView-kZ2yGen8.css +1 -0
- package/dist/web-ui/assets/LoginView-B1naaT8E.js +1 -0
- package/dist/web-ui/assets/LoginView-CSfb59pE.css +1 -0
- package/dist/web-ui/assets/LogsView-CCjJTjvZ.css +1 -0
- package/dist/web-ui/assets/LogsView-YtH8gJPU.js +9 -0
- package/dist/web-ui/assets/ProvidersView-Caqpg_0F.css +1 -0
- package/dist/web-ui/assets/ProvidersView-DWtS_e7t.js +31 -0
- package/dist/web-ui/assets/ServiceStatusView-D3ybS2T-.js +39 -0
- package/dist/web-ui/assets/ServiceStatusView-DrPoYMN-.css +1 -0
- package/dist/web-ui/assets/SettingsView-D1kbH5Ev.css +1 -0
- package/dist/web-ui/assets/SettingsView-DepOaZYg.js +1 -0
- package/dist/web-ui/assets/SetupView-BwDwokAd.js +1 -0
- package/dist/web-ui/assets/SetupView-pS9nSnLg.css +1 -0
- package/dist/web-ui/assets/clipboard-aCBIMfw7.js +1 -0
- package/dist/web-ui/assets/config-CdOq1p3C.js +1 -0
- package/dist/web-ui/assets/format-kTdM4RVv.js +1 -0
- package/dist/web-ui/assets/index-BecfPmag.css +1 -0
- package/dist/web-ui/assets/index-CgzCvxTY.js +96 -0
- package/dist/web-ui/assets/providers-i7t_wEzk.js +1 -0
- package/dist/web-ui/assets/useLoadError-UA3r7sR9.js +1 -0
- package/dist/web-ui/assets/useManagerApi-CBQNomtR.js +1 -0
- package/dist/web-ui/assets/useToast-DNMhOOeI.js +1 -0
- package/dist/web-ui/assets/version-BKHjE_LF.js +1 -0
- package/dist/web-ui/config.js +7 -0
- package/dist/web-ui/index.html +15 -0
- package/docs/DESIGN.md +90 -0
- package/ezllm.config.example.json +33 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.copy-text[data-v-2044e04d]{color:#409eff;cursor:pointer}.copy-text[data-v-2044e04d]:hover{text-decoration:underline}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as m,d as ce,l as ve,y as pe,e as x,i as v,c as S,w as s,j as B,h as l,A as I,a as f,k as me,o as p,g as _,b as fe,t as d,f as o,F as _e,z as ge,p as L,_ as ye}from"./index-CgzCvxTY.js";import{m as he}from"./useManagerApi-CBQNomtR.js";import{u as we}from"./providers-i7t_wEzk.js";import{u as be}from"./useToast-DNMhOOeI.js";import{u as ke}from"./useLoadError-UA3r7sR9.js";import{c as H,f as y,a as De,b as Ce,d as xe}from"./format-kTdM4RVv.js";import{c as Me}from"./clipboard-aCBIMfw7.js";import"./config-CdOq1p3C.js";function Se(R){const{loadError:D,run:V}=ke(R),h=m(null);function P(n){const g=async()=>{const w=await V(n);return w?h.value===g&&(h.value=null):h.value=g,w};return g}function T(n){(h.value??n)()}return{loadError:D,track:P,retry:T}}const Ve={class:"flex-col-gap"},Pe=["onClick"],Te={key:1},$e={class:"flex-between"},Ae={class:"flex-gap-8"},Be={class:"usage-grid"},Ie={class:"usage-cell"},Le={class:"usage-num orange"},Re={class:"usage-cell"},Ye={class:"usage-num blue"},Ne={class:"usage-cell"},Ue={class:"usage-num green"},Fe={class:"usage-cell"},Ee={class:"usage-num purple"},Ke={class:"usage-cell"},qe={class:"usage-num purple"},ze={key:0,class:"usage-cell"},je={class:"usage-num gray"},Oe={key:0},We=["onClick"],Ge=ce({__name:"DashboardView",setup(R){const D=we(),{toast:V}=be(),{loadError:h,track:P,retry:T}=Se(),n=m(null),g=m(!0),w=m(""),M=m("today"),$=t=>{const e=t.getFullYear(),a=String(t.getMonth()+1).padStart(2,"0"),c=String(t.getDate()).padStart(2,"0");return`${e}-${a}-${c}`},Y=$(new Date),b=m([Y,Y]),J=t=>{const e=new Date;let a,c=e;if(t==="today")a=e;else if(t==="yesterday")a=new Date(e),a.setDate(e.getDate()-1),c=a;else if(t==="beforeYesterday")a=new Date(e),a.setDate(e.getDate()-2),c=a;else if(t==="last3days")a=new Date(e),a.setDate(e.getDate()-2);else if(t==="week"){a=new Date(e);const r=(e.getDay()+6)%7;a.setDate(e.getDate()-r)}else if(t==="month")a=new Date(e.getFullYear(),e.getMonth(),1);else return;M.value=t,b.value=[$(a),$(c)],C()},Q=t=>{t?J(t):(M.value="",b.value=null,C())},X=()=>{M.value="",C()},Z=L(()=>{var e;const t=new Set;for(const a of D.suppliers)for(const c of a.models)t.add(c.modelName);if((e=n.value)!=null&&e.models)for(const a of n.value.models)t.add(a.model);return[...t].sort()}),ee=H(),C=P(async()=>{var e;const t=ee();g.value=!0;try{const a=new URLSearchParams;w.value&&a.set("model",w.value),((e=b.value)==null?void 0:e.length)===2&&(a.set("startDate",b.value[0]),a.set("endDate",b.value[1]));const c=a.toString(),r=await I.get(`/api/usage${c?`?${c}`:""}`);if(!t())return;n.value=r}catch(a){if(!t())return;throw a}finally{t()&&(g.value=!1)}}),te=H(),N=P(async()=>{const t=te();try{await Promise.all([C(),D.loadProviders(),I.get("/api/status").then(e=>A.value=e.listenPort).catch(()=>A.value)])}catch(e){if(!t())return;throw e}finally{t()&&(g.value=!1)}}),ae=()=>T(N),le=window.location.hostname,A=m(Number(window.location.port)||null),oe=L(()=>xe({protocol:window.location.protocol,hostname:le,port:A.value})),U=m(null),F=m(null),E=m(!1),K=m(Date.now()),q=async()=>{try{const[t,e]=await Promise.all([he.processes(),I.get("/api/config").catch(()=>null)]);U.value=t[0]??null,E.value=e===null,F.value=(e==null?void 0:e.masterKey)??"",K.value=Date.now()}catch{}},se=t=>{if(!t.startedAt)return"-";let e=Math.max(0,Math.floor((K.value-t.startedAt)/1e3));const a=Math.floor(e/86400);e-=a*86400;const c=Math.floor(e/3600);e-=c*3600;const r=Math.floor(e/60);return e-=r*60,[a?`${a}天`:"",c?`${c}时`:"",r?`${r}分`:"",`${e}秒`].filter(Boolean).join(" ")},ne=L(()=>{const t=[{key:"API 地址",value:oe.value},{key:"API 密钥",value:E.value?"获取失败,请刷新重试":F.value||"未设置(/v1 免鉴权)"},{key:"供应商数量",value:String(D.providerCount)},{key:"模型总数",value:String(D.totalModelCount)}],e=U.value;return e&&t.push({key:"运行状态",value:e.status==="online"?"运行中":e.status==="errored"?"异常":"已停止"},{key:"PID",value:String(e.pid??"-")},{key:"运行时长",value:se(e)},{key:"内存占用",value:Ce(e.memory)}),t});let z;const j=async t=>{await Me(t)?V("已复制到剪贴板","success"):V("复制失败","error")};return ve(()=>{N(),q(),z=window.setInterval(q,1e4)}),pe(()=>window.clearInterval(z)),(t,e)=>{const a=f("el-button"),c=f("el-alert"),r=f("el-table-column"),O=f("el-table"),W=f("el-card"),k=f("el-option"),G=f("el-select"),re=f("el-date-picker"),ue=f("el-tag"),ie=f("el-empty"),de=me("loading");return p(),x("div",Ve,[v(h)?(p(),S(c,{key:0,title:v(h),type:"error","show-icon":"",closable:!1},{default:s(()=>[l(a,{size:"small",onClick:ae},{default:s(()=>[...e[3]||(e[3]=[_("重试",-1)])]),_:1})]),_:1},8,["title"])):B("",!0),l(W,{shadow:"never"},{header:s(()=>[...e[4]||(e[4]=[o("span",{class:"fw-600"},"服务信息",-1)])]),default:s(()=>[fe((p(),S(O,{border:"",data:ne.value,"show-header":!1,class:"full-width"},{default:s(()=>[l(r,{prop:"key",width:"160"}),l(r,null,{default:s(({row:u})=>[u.key==="API 地址"||u.key==="API 密钥"?(p(),x("span",{key:0,class:"copy-text",onClick:i=>j(u.value)},d(u.value),9,Pe)):(p(),x("span",Te,d(u.value),1))]),_:1})]),_:1},8,["data"])),[[de,g.value]])]),_:1}),n.value?(p(),S(W,{key:1,shadow:"never"},{header:s(()=>[o("div",$e,[e[6]||(e[6]=o("span",{class:"fw-600"},"用量统计",-1)),o("div",Ae,[l(G,{modelValue:w.value,"onUpdate:modelValue":e[0]||(e[0]=u=>w.value=u),placeholder:"全部模型",clearable:"",filterable:"",style:{width:"220px"},onChange:v(C)},{default:s(()=>[(p(!0),x(_e,null,ge(Z.value,u=>(p(),S(k,{key:u,label:u,value:u},null,8,["label","value"]))),128))]),_:1},8,["modelValue","onChange"]),l(G,{modelValue:M.value,"onUpdate:modelValue":e[1]||(e[1]=u=>M.value=u),placeholder:"时间范围",clearable:"",style:{width:"130px"},onChange:Q},{default:s(()=>[l(k,{label:"今天",value:"today"}),l(k,{label:"昨天",value:"yesterday"}),l(k,{label:"前天",value:"beforeYesterday"}),l(k,{label:"近三天",value:"last3days"}),l(k,{label:"本周",value:"week"}),l(k,{label:"本月",value:"month"})]),_:1},8,["modelValue"]),l(re,{modelValue:b.value,"onUpdate:modelValue":e[2]||(e[2]=u=>b.value=u),type:"daterange","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期","value-format":"YYYY-MM-DD",style:{width:"260px"},onChange:X},null,8,["modelValue"]),l(a,{loading:g.value,onClick:v(C)},{default:s(()=>[...e[5]||(e[5]=[_("刷新",-1)])]),_:1},8,["loading","onClick"])]),l(ue,{type:"info"},{default:s(()=>[_(d(n.value.total.calls)+" 次调用",1)]),_:1})])]),default:s(()=>{var u;return[o("div",Be,[o("div",Ie,[o("div",Le,d(v(y)(n.value.total.total_tokens)),1),e[7]||(e[7]=o("div",{class:"usage-label"},"总 Token",-1))]),o("div",Re,[o("div",Ye,d(v(y)(n.value.total.input_tokens)),1),e[8]||(e[8]=o("div",{class:"usage-label"},"输入 Token",-1))]),o("div",Ne,[o("div",Ue,d(v(y)(n.value.total.output_tokens)),1),e[9]||(e[9]=o("div",{class:"usage-label"},"输出 Token",-1))]),o("div",Fe,[o("div",Ee,d(v(y)(n.value.total.cache_read_tokens)),1),e[10]||(e[10]=o("div",{class:"usage-label"},"缓存读取",-1))]),o("div",Ke,[o("div",qe,d(n.value.total.cache_rate!=null?n.value.total.cache_rate+"%":"-"),1),e[11]||(e[11]=o("div",{class:"usage-label"},"缓存命中率",-1))]),n.value.logStorageMB!=null?(p(),x("div",ze,[o("div",je,d(n.value.logStorageMB),1),e[12]||(e[12]=o("div",{class:"usage-label"},"日志占用 (MB)",-1))])):B("",!0)]),(u=n.value.models)!=null&&u.length?(p(),x("div",Oe,[e[13]||(e[13]=o("div",{class:"section-title"},"模型用量",-1)),l(O,{data:n.value.models,border:"",stripe:"",class:"full-width"},{default:s(()=>[l(r,{prop:"model",label:"模型","min-width":"200"},{default:s(({row:i})=>[o("span",{class:"copy-text",onClick:He=>j(i.model)},d(i.model),9,We)]),_:1}),l(r,{label:"调用次数",width:"90",align:"center"},{default:s(({row:i})=>[_(d(i.calls),1)]),_:1}),l(r,{label:"平均耗时",width:"110",align:"center"},{default:s(({row:i})=>[_(d(v(De)(i.avg_duration)),1)]),_:1}),l(r,{label:"总 Token",width:"140",align:"center"},{default:s(({row:i})=>[_(d(v(y)(i.total_tokens)),1)]),_:1}),l(r,{label:"输入 Token",width:"140",align:"center"},{default:s(({row:i})=>[_(d(v(y)(i.input_tokens)),1)]),_:1}),l(r,{label:"输出 Token",width:"140",align:"center"},{default:s(({row:i})=>[_(d(v(y)(i.output_tokens)),1)]),_:1}),l(r,{label:"缓存读取",width:"130",align:"center"},{default:s(({row:i})=>[_(d(v(y)(i.cache_read_tokens)),1)]),_:1}),l(r,{label:"缓存命中率",width:"110",align:"center"},{default:s(({row:i})=>[_(d(i.cache_rate!=null?i.cache_rate+"%":"-"),1)]),_:1})]),_:1},8,["data"])])):(p(),S(ie,{key:1,description:"暂无调用记录","image-size":60}))]}),_:1})):B("",!0)])}}}),ot=ye(Ge,[["__scopeId","data-v-2044e04d"]]);export{ot as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as M,u as q,c as V,w as t,r as y,a as i,o as c,b as F,e as D,f as d,g as n,F as L,h as a,t as C,i as N,j as b,E as j,k as I,_ as O,l as P,m as G,n as H,p as S,q as J,s as K,v as Q,x as X}from"./index-CgzCvxTY.js";import{m as B,w as Y}from"./useManagerApi-CBQNomtR.js";import{u as Z}from"./useToast-DNMhOOeI.js";import{i as ee,u as te}from"./version-BKHjE_LF.js";const le={class:"check-body"},oe={class:"version-row"},se={class:"version-row"},ae={class:"muted-sm"},ne=M({__name:"UpdateCheckDialog",props:{modelValue:{type:Boolean,default:!1},modelModifiers:{}},emits:["update:modelValue"],setup(E){const{toast:h}=Z(),$=q(E,"modelValue"),_=y(!1),g=y(!1),x=y(null),l=y(null),k=y(null),p=y(null);let o=null;const s=()=>o==null?void 0:o.abort(),w=u=>new Date(u).toLocaleString(),T=u=>`https://www.npmjs.com/package/ezllm/v/${u}`,A=async()=>{l.value=null,k.value=null,p.value=null,_.value=!0;try{const u=await B.update();if(x.value=u,!u.supported)return;l.value=await B.checkUpdate()}catch(u){k.value=u.message||"检查更新失败"}finally{_.value=!1}},z=async()=>{var v;if(!l.value)return;const u=l.value.latestVersion;try{await j.confirm(`确定更新到 ${u}?服务会自动重启并在启动时安装新版本:重启期间管理台短暂不可访问(预计 1~3 分钟),更新完成后自动恢复。`,"更新确认",{confirmButtonText:"立即更新",cancelButtonText:"取消",type:"warning"})}catch{return}g.value=!0;const e=new AbortController;o=e;try{const f=await B.update(),m=await B.applyUpdate();if(!m.updated){p.value=`已是最新版本 ${m.toVersion}`,l.value={hasUpdate:!1,currentVersion:m.toVersion,latestVersion:m.toVersion,checkedAt:Date.now()};return}p.value=`正在重启服务并安装 ${m.toVersion}(预计 1~3 分钟):重启期间管理台短暂不可访问,完成后这里会自动显示结果。`;const r=await Y({targetVersion:m.toVersion,sinceAppliedAt:((v=f.lastApply)==null?void 0:v.appliedAt)??null,signal:e.signal});if(e.signal.aborted)return;r&&!r.error?(h(`已更新到 ${r.toVersion}`,"success"),p.value=`已更新 ${r.fromVersion} → ${r.toVersion},服务已在新版本上运行。`,l.value={hasUpdate:!1,currentVersion:r.toVersion,latestVersion:r.toVersion,checkedAt:Date.now()}):r!=null&&r.error?(h(`更新失败:${r.error}`,"error"),p.value=te(r.error)):p.value="更新仍在进行(安装耗时较长):稍后刷新页面查看最新状态。"}catch(f){h(f.message||"更新失败","error")}finally{g.value=!1,o===e&&(o=null)}};return(u,e)=>{const v=i("el-alert"),f=i("el-tag"),m=i("el-link"),r=i("el-button"),R=i("el-dialog"),W=I("loading");return c(),V(R,{modelValue:$.value,"onUpdate:modelValue":e[2]||(e[2]=U=>$.value=U),title:"检查更新",width:"420px","close-on-click-modal":!g.value,onOpen:A,onClose:s},{footer:t(()=>{var U;return[(U=l.value)!=null&&U.hasUpdate?(c(),V(r,{key:0,type:"primary",loading:g.value,onClick:z},{default:t(()=>[n(C(g.value?"更新中...":"立即更新"),1)]),_:1},8,["loading"])):b("",!0),a(r,{onClick:e[1]||(e[1]=me=>$.value=!1)},{default:t(()=>[...e[11]||(e[11]=[n("关闭",-1)])]),_:1})]}),default:t(()=>[F((c(),D("div",le,[x.value&&!x.value.supported?(c(),V(v,{key:0,title:"当前为源码运行模式,更新功能不可用",type:"info","show-icon":"",closable:!1},{default:t(()=>[...e[3]||(e[3]=[d("div",{class:"alert-hint"},[n(" 仅 npm 全局安装的包支持自动更新。本地开发用仓库里的 "),d("code",null,"pnpm upgrade:local"),n(" 更新运行中的服务。 ")],-1)])]),_:1})):l.value?(c(),D(L,{key:1},[d("div",oe,[e[5]||(e[5]=d("span",{class:"version-label"},"当前版本",-1)),a(f,{size:"small"},{default:t(()=>[n(C(l.value.currentVersion),1)]),_:1}),N(ee)(l.value.currentVersion)?(c(),V(f,{key:0,type:"warning",size:"small","disable-transitions":""},{default:t(()=>[...e[4]||(e[4]=[n("本地构建",-1)])]),_:1})):b("",!0)]),d("div",se,[e[6]||(e[6]=d("span",{class:"version-label"},"最新版本",-1)),a(f,{type:l.value.hasUpdate?"warning":"success",size:"small","disable-transitions":""},{default:t(()=>[n(C(l.value.latestVersion),1)]),_:1},8,["type"])]),a(v,{title:l.value.hasUpdate?`发现新版本 ${l.value.latestVersion}(当前 ${l.value.currentVersion})`:`已是最新版本 ${l.value.currentVersion}`,type:l.value.hasUpdate?"warning":"success","show-icon":"",closable:!1,class:"mt-12"},null,8,["title","type"]),d("div",ae,[n(" 检查时间:"+C(w(l.value.checkedAt))+" ",1),l.value.hasUpdate?(c(),D(L,{key:0},[e[8]||(e[8]=n(" · ",-1)),a(m,{type:"primary",href:T(l.value.latestVersion),target:"_blank"},{default:t(()=>[...e[7]||(e[7]=[n("在 npm 查看该版本",-1)])]),_:1},8,["href"])],64)):b("",!0)])],64)):!_.value&&k.value?(c(),V(v,{key:2,title:k.value,type:"error","show-icon":"",closable:!1},{default:t(()=>[e[10]||(e[10]=d("div",{class:"alert-hint"}," 检查需访问 npm 源,可能是网络不可达或版本号解析失败;稍后重试即可。 ",-1)),a(r,{size:"small",class:"mt-8",onClick:A},{default:t(()=>[...e[9]||(e[9]=[n("重试",-1)])]),_:1})]),_:1},8,["title"])):b("",!0)])),[[W,_.value]]),p.value?(c(),V(v,{key:0,title:p.value,type:"info","show-icon":"",class:"mt-12",onClose:e[0]||(e[0]=U=>p.value=null)},null,8,["title"])):b("",!0)]),_:1},8,["modelValue","close-on-click-modal"])}}}),re=O(ne,[["__scopeId","data-v-ea1efda8"]]),ue={class:"layout"},ie={class:"header-nav"},de={class:"header-actions"},pe={class:"main"},ce={class:"page"},we=M({__name:"LayoutView",setup(E){const h=Q(),$=K(),_=y(!1);P(()=>{G()});const g=S(()=>{var o;return((o=X.value)==null?void 0:o.authRequired)!==!1}),x=S(()=>{if(!g.value)return"免登录";const o=localStorage.getItem("webui_token")||"";try{return atob(o).split(":")[0]||"用户"}catch{return"用户"}}),l=S(()=>{const o=h.path;return o==="/"?"/":o.startsWith("/providers")?"/providers":o.startsWith("/service-status")?"/service-status":o.startsWith("/settings")?"/settings":o.startsWith("/logs")?"/logs":"/"}),k=()=>{J(),$.push("/login")},p=o=>{o==="logout"&&k(),o==="check-update"&&(_.value=!0)};return(o,s)=>{const w=i("el-menu-item"),T=i("el-menu"),A=i("el-icon"),z=i("el-button"),u=i("el-dropdown-item"),e=i("el-dropdown-menu"),v=i("el-dropdown"),f=i("el-header"),m=i("router-view");return c(),D("div",ue,[a(f,{class:"header"},{default:t(()=>[s[8]||(s[8]=d("h1",null,[d("span",null,"E"),n("LLM")],-1)),d("nav",ie,[a(T,{mode:"horizontal","default-active":l.value,ellipsis:!1,router:"",class:"header-menu"},{default:t(()=>[a(w,{index:"/"},{default:t(()=>[...s[1]||(s[1]=[n("首页",-1)])]),_:1}),a(w,{index:"/providers"},{default:t(()=>[...s[2]||(s[2]=[n("供应商管理",-1)])]),_:1}),a(w,{index:"/service-status"},{default:t(()=>[...s[3]||(s[3]=[n("服务状态",-1)])]),_:1}),a(w,{index:"/logs"},{default:t(()=>[...s[4]||(s[4]=[n("日志",-1)])]),_:1}),a(w,{index:"/settings"},{default:t(()=>[...s[5]||(s[5]=[n("设置",-1)])]),_:1})]),_:1},8,["default-active"])]),d("div",de,[a(v,{trigger:"click",onCommand:p,class:"ml-12"},{dropdown:t(()=>[a(e,null,{default:t(()=>[a(u,{command:"check-update"},{default:t(()=>[...s[6]||(s[6]=[n("检查更新",-1)])]),_:1}),g.value?(c(),V(u,{key:0,command:"logout",divided:""},{default:t(()=>[...s[7]||(s[7]=[n("退出",-1)])]),_:1})):b("",!0)]),_:1})]),default:t(()=>[a(z,null,{default:t(()=>[n(C(x.value)+" ",1),a(A,{class:"el-icon--right"},{default:t(()=>[a(N(H))]),_:1})]),_:1})]),_:1})])]),_:1}),d("main",pe,[d("div",ce,[a(m)])]),a(re,{modelValue:_.value,"onUpdate:modelValue":s[0]||(s[0]=r=>_.value=r)},null,8,["modelValue"])])}}});export{we as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.mt-8[data-v-ea1efda8]{margin-top:8px}.mt-12[data-v-ea1efda8]{margin-top:12px}.check-body[data-v-ea1efda8]{min-height:80px}.alert-hint[data-v-ea1efda8]{margin-top:4px;font-size:12px;line-height:1.6}.alert-hint code[data-v-ea1efda8]{background:var(--el-fill-color-light);padding:1px 6px;border-radius:4px;font-size:12px}.version-row[data-v-ea1efda8]{display:flex;align-items:center;gap:8px;margin-bottom:8px}.version-label[data-v-ea1efda8]{color:var(--el-text-color-secondary);font-size:13px}.muted-sm[data-v-ea1efda8]{margin-top:8px;color:var(--el-text-color-secondary);font-size:12px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as h,e as b,h as o,w as l,a as t,o as _,f as k,a3 as x,a8 as f,c as C,j as L,g as B,r as i,A as N,ai as K,s as A,_ as E}from"./index-CgzCvxTY.js";const I={class:"login-wrap"},M=h({__name:"LoginView",setup(T){const v=A(),n=i(""),s=i(""),a=i(""),d=i(!1);async function r(){if(!n.value){a.value="请输入用户名";return}if(!s.value){a.value="请输入密码";return}d.value=!0,a.value="";try{const u=await N.post("/api/auth/login",{username:n.value.trim(),password:s.value});K(u.token),v.push("/")}catch(u){a.value=u.message||"登录失败"}finally{d.value=!1}}return(u,e)=>{const p=t("el-input"),m=t("el-form-item"),w=t("el-alert"),g=t("el-button"),V=t("el-form"),y=t("el-card");return _(),b("div",I,[o(y,{shadow:"hover",class:"login-card"},{default:l(()=>[e[3]||(e[3]=k("h2",{class:"login-title"},"EZLLM",-1)),o(V,{"label-position":"top",onSubmit:x(r,["prevent"])},{default:l(()=>[o(m,{label:"用户名"},{default:l(()=>[o(p,{modelValue:n.value,"onUpdate:modelValue":e[0]||(e[0]=c=>n.value=c),placeholder:"请输入用户名",onKeyup:f(r,["enter"])},null,8,["modelValue"])]),_:1}),o(m,{label:"密码"},{default:l(()=>[o(p,{modelValue:s.value,"onUpdate:modelValue":e[1]||(e[1]=c=>s.value=c),type:"password",placeholder:"请输入密码","show-password":"",onKeyup:f(r,["enter"])},null,8,["modelValue"])]),_:1}),a.value?(_(),C(w,{key:0,title:a.value,type:"error","show-icon":"",class:"mb-16"},null,8,["title"])):L("",!0),o(g,{type:"primary",class:"full-width",loading:d.value,onClick:r},{default:l(()=>[...e[2]||(e[2]=[B(" 登录 ",-1)])]),_:1},8,["loading"])]),_:1})]),_:1})])}}}),j=E(M,[["__scopeId","data-v-c8c59fbd"]]);export{j as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.login-card[data-v-c8c59fbd]{max-width:400px;width:100%}.login-title[data-v-c8c59fbd]{text-align:center;margin-bottom:24px;color:#3b82f6}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ip-link[data-v-ba28eb07]{color:#409eff;cursor:pointer}.ip-link[data-v-ba28eb07]:hover{text-decoration:underline}.ip-pop[data-v-ba28eb07]{font-size:13px;min-height:20px}.ip-pop-row[data-v-ba28eb07]{display:flex;gap:8px;margin-bottom:4px}.ip-pop-label[data-v-ba28eb07]{color:#909399;flex-shrink:0}.ip-pop-error[data-v-ba28eb07]{color:#f56c6c}.ip-pop-link[data-v-ba28eb07]{color:#409eff;font-size:13px}.error-text[data-v-ba28eb07]{color:#f56c6c}.pane-bar[data-v-ba28eb07]{display:flex;justify-content:flex-end;margin-bottom:8px;flex-shrink:0}.json-block[data-v-ba28eb07]{background:#f5f7fa;border:1px solid #e4e7ed;border-radius:4px;padding:12px;font-size:13px;line-height:1.5;overflow:auto;white-space:pre-wrap;word-break:break-all;flex:1;min-height:0}.detail-content[data-v-ba28eb07]{height:78vh;display:flex;flex-direction:column;overflow:hidden}.detail-content[data-v-ba28eb07] .el-tabs{flex:1;min-height:0;display:flex;flex-direction:column}.detail-content[data-v-ba28eb07] .el-tabs__content{flex:1;min-height:0}.detail-content[data-v-ba28eb07] .el-tab-pane{height:100%;display:flex;flex-direction:column;overflow:auto}.copy-btn[data-v-ba28eb07]{margin-left:8px;padding:2px 10px;font-size:12px}.logs-page[data-v-5b05299d]{height:calc(100vh - 124px);display:flex;flex-direction:column;overflow:hidden}.request-id[data-v-5b05299d]{cursor:pointer;font-family:ui-monospace,Consolas,monospace;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.request-id[data-v-5b05299d]:hover{color:var(--el-color-primary)}.filter-bar[data-v-5b05299d]{display:flex;gap:12px;align-items:center;flex-wrap:nowrap}.filter-bar .keyword-input[data-v-5b05299d]{flex:1;min-width:160px}.filter-bar .push-right[data-v-5b05299d]{margin-left:auto}.filter-bar[data-v-5b05299d] .el-button+.el-button{margin-left:0}.mt-16[data-v-5b05299d]{margin-top:16px}.table-card[data-v-5b05299d]{flex:1;min-height:0;overflow:hidden}.table-card[data-v-5b05299d] .el-card__body{height:100%;display:flex;flex-direction:column}.table-wrap[data-v-5b05299d]{flex:1;min-height:0}.pagination-bar[data-v-5b05299d]{margin-top:16px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{d as ae,a as _,k as se,o as d,c as x,w as l,i as p,h as e,g as u,j as E,e as g,t as r,b as oe,F as H,f as i,r as m,A as Q,_ as ne,l as ke,z as we,a8 as xe,p as he,E as Ce}from"./index-CgzCvxTY.js";import{u as De}from"./providers-i7t_wEzk.js";import{u as re}from"./useToast-DNMhOOeI.js";import{u as ue}from"./useLoadError-UA3r7sR9.js";import{c as ie}from"./clipboard-aCBIMfw7.js";import{e as de,f as Y,a as pe,g as ce,h as S,i as $e,c as Ve}from"./format-kTdM4RVv.js";import"./config-CdOq1p3C.js";const qe={key:1,class:"detail-content"},Ie={key:0,class:"ip-link"},Se={class:"ip-pop"},ze={class:"ip-pop-row"},Re={key:0,class:"ip-pop-row"},Ue={key:1,class:"ip-pop-error"},je={key:2},Le=["href"],Te={key:1},Ee={key:1},Ne={class:"error-text"},Pe={class:"pane-bar"},Be={class:"json-block"},Ye={class:"pane-bar"},Me={class:"json-block"},Fe={class:"pane-bar"},Ke={class:"json-block"},Ae={class:"pane-bar"},We={class:"json-block"},Ge={class:"pane-bar"},Je={class:"json-block"},Oe={class:"pane-bar"},He={class:"json-block"},Qe={class:"pane-bar"},Xe={class:"json-block"},Ze={class:"pane-bar"},et={class:"json-block"},tt=ae({__name:"LogDetailDialog",setup(P,{expose:h}){const{toast:V}=re(),{loadError:M,run:X}=ue(),q=m(!1),t=m(null),z=m("info"),R=m(!1),U=m(null),j=c=>{U.value=c,q.value=!0,t.value=null,z.value="info",X(async()=>{const a=c.id?`?id=${c.id}`:`?_file=${encodeURIComponent(c._file)}`,f=await Q.get("/api/logs/detail"+a);f&&f.detail?t.value={...f.detail,...f.meta}:t.value=f})},F=()=>{U.value&&j(U.value)};h({open:j});const y=async c=>{await ie(c)?V("已复制到剪贴板","success"):V("复制失败","error")},L=async c=>{if(!(c._ipInfo||c._ipInfoError)){R.value=!0;try{const a=await Q.get(`/api/logs/ipinfo?ip=${encodeURIComponent(c.ip)}`);a.error?c._ipInfoError=a.error:c._ipInfo=a}catch{c._ipInfoError="查询失败"}finally{R.value=!1}}},B=c=>[c.country,c.region,c.city].filter(Boolean).join(" · ")||"-";return(c,a)=>{const f=_("el-button"),A=_("el-alert"),b=_("el-descriptions-item"),Z=_("el-tag"),W=_("el-divider"),K=_("el-popover"),ee=_("el-descriptions"),C=_("el-tab-pane"),G=_("el-tabs"),te=_("el-dialog"),N=se("loading");return d(),x(te,{modelValue:q.value,"onUpdate:modelValue":a[11]||(a[11]=D=>q.value=D),title:"日志详情",width:"80%",top:"5vh","destroy-on-close":""},{default:l(()=>[p(M)?(d(),x(A,{key:0,title:p(M),type:"error","show-icon":"",closable:!1,class:"mb-16"},{default:l(()=>[e(f,{size:"small",onClick:F},{default:l(()=>[...a[12]||(a[12]=[u("重试",-1)])]),_:1})]),_:1},8,["title"])):E("",!0),t.value?(d(),g("div",qe,[e(G,{modelValue:z.value,"onUpdate:modelValue":a[10]||(a[10]=D=>z.value=D)},{default:l(()=>{var D,J,$;return[e(C,{label:"基本信息",name:"info"},{default:l(()=>{var w;return[e(ee,{column:2,border:""},{default:l(()=>[e(b,{label:"时间"},{default:l(()=>[u(r(p(de)(t.value.time)),1)]),_:1}),e(b,{label:"模型"},{default:l(()=>[u(r(t.value.model),1)]),_:1}),e(b,{label:"方法"},{default:l(()=>[u(r(t.value.method),1)]),_:1}),e(b,{label:"路径"},{default:l(()=>[u(r(t.value.path),1)]),_:1}),e(b,{label:"状态码"},{default:l(()=>[u(r(t.value.status),1)]),_:1}),e(b,{label:"流式"},{default:l(()=>[e(Z,{type:t.value.stream?"warning":"info"},{default:l(()=>[u(r(t.value.stream?"是":"否"),1)]),_:1},8,["type"])]),_:1}),e(b,{label:"IP"},{default:l(()=>[t.value.ip?(d(),g("span",Ie,[e(K,{placement:"right",width:"240",trigger:"click",onShow:a[0]||(a[0]=o=>L(t.value))},{reference:l(()=>[i("span",null,r(t.value.ip),1)]),default:l(()=>[oe((d(),g("div",Se,[t.value._ipInfo?(d(),g(H,{key:0},[i("div",ze,[a[13]||(a[13]=i("span",{class:"ip-pop-label"},"归属地",-1)),i("span",null,r(B(t.value._ipInfo)),1)]),t.value._ipInfo.isp?(d(),g("div",Re,[a[14]||(a[14]=i("span",{class:"ip-pop-label"},"运营商",-1)),i("span",null,r(t.value._ipInfo.isp),1)])):E("",!0)],64)):t.value._ipInfoError?(d(),g("div",Ue,r(t.value._ipInfoError),1)):(d(),g("span",je,"查询中...")),e(W,{style:{margin:"8px 0"}}),i("a",{class:"ip-pop-link",href:`https://m.ip138.com/iplookup.php?ip=${encodeURIComponent(t.value.ip)}`,target:"_blank"},"在 ip138 查看",8,Le)])),[[N,R.value]])]),_:1})])):(d(),g("span",Te,"-"))]),_:1}),e(b,{label:"Session"},{default:l(()=>[u(r(t.value.session_id||"-"),1)]),_:1}),e(b,{label:"Request ID"},{default:l(()=>[t.value.request_id?(d(),g("span",{key:0,class:"request-id",title:"点击复制(可用于关联控制台日志与检索)",onClick:a[1]||(a[1]=o=>y(t.value.request_id))},r(t.value.request_id),1)):(d(),g("span",Ee,"-"))]),_:1}),e(b,{label:"输入 Token(含缓存读取)"},{default:l(()=>[u(r(p(Y)(t.value.input_tokens??0)),1)]),_:1}),e(b,{label:"输出 Token"},{default:l(()=>[u(r(p(Y)(t.value.output_tokens??0)),1)]),_:1}),e(b,{label:"缓存读取"},{default:l(()=>[u(r(p(Y)(t.value.cache_read_tokens??0)),1)]),_:1}),e(b,{label:"请求耗时"},{default:l(()=>[u(r(p(pe)(t.value.duration)),1)]),_:1}),e(b,{label:"缓存命中率"},{default:l(()=>[u(r(p(ce)(t.value)),1)]),_:1}),t.value.error?(d(),x(b,{key:0,label:"错误",span:2},{default:l(()=>[i("span",Ne,r(t.value.error),1)]),_:1})):E("",!0)]),_:1}),(w=t.value.response)!=null&&w.truncated?(d(),x(A,{key:0,class:"mt-16",type:"warning",closable:!1,title:"内容超过单请求捕获上限,已截断"})):E("",!0)]}),_:1}),(D=t.value.response)!=null&&D._capture?(d(),g(H,{key:0},[e(C,{label:"客户端请求",name:"inbound"},{default:l(()=>[i("div",Pe,[e(f,{size:"small",class:"copy-btn",onClick:a[2]||(a[2]=w=>y(p(S)(t.value.response.inbound_request)))},{default:l(()=>[...a[15]||(a[15]=[u(" 复制 ",-1)])]),_:1})]),i("pre",Be,r(p(S)(t.value.response.inbound_request)),1)]),_:1}),e(C,{label:"转发上游的请求",name:"upstreamReq"},{default:l(()=>[i("div",Ye,[e(f,{size:"small",class:"copy-btn",onClick:a[3]||(a[3]=w=>y(p(S)(t.value.response.upstream_request)))},{default:l(()=>[...a[16]||(a[16]=[u(" 复制 ",-1)])]),_:1})]),i("pre",Me,r(p(S)(t.value.response.upstream_request)),1)]),_:1}),t.value.response.upstream_response_text?(d(),x(C,{key:0,label:"上游响应(原始)",name:"upstreamRes"},{default:l(()=>[i("div",Fe,[e(f,{size:"small",class:"copy-btn",onClick:a[4]||(a[4]=w=>y(t.value.response.upstream_response_text))},{default:l(()=>[...a[17]||(a[17]=[u(" 复制 ",-1)])]),_:1})]),i("pre",Ke,r(p($e)(t.value.response.upstream_response_text)),1)]),_:1})):(J=t.value.response.upstream_stream_frames)!=null&&J.length?(d(),x(C,{key:1,label:`上游响应(原始流,${t.value.response.upstream_stream_frames.length} 帧)`,name:"upstreamStream"},{default:l(()=>[i("div",Ae,[e(f,{size:"small",class:"copy-btn",onClick:a[5]||(a[5]=w=>y(t.value.response.upstream_stream_frames.join(`
|
|
2
|
+
|
|
3
|
+
`)))},{default:l(()=>[...a[18]||(a[18]=[u(" 复制 ",-1)])]),_:1})]),i("pre",We,r(t.value.response.upstream_stream_frames.join(`
|
|
4
|
+
|
|
5
|
+
`)),1)]),_:1},8,["label"])):E("",!0),t.value.response.client_response!==void 0&&t.value.response.client_response!==null?(d(),x(C,{key:2,label:"回写客户端(转换后)",name:"clientRes"},{default:l(()=>[i("div",Ge,[e(f,{size:"small",class:"copy-btn",onClick:a[6]||(a[6]=w=>y(p(S)(t.value.response.client_response)))},{default:l(()=>[...a[19]||(a[19]=[u(" 复制 ",-1)])]),_:1})]),i("pre",Je,r(p(S)(t.value.response.client_response)),1)]),_:1})):($=t.value.response.client_stream_frames)!=null&&$.length?(d(),x(C,{key:3,label:`回写客户端(${t.value.response.client_stream_frames.length} 帧)`,name:"clientStream"},{default:l(()=>[i("div",Oe,[e(f,{size:"small",class:"copy-btn",onClick:a[7]||(a[7]=w=>y(t.value.response.client_stream_frames.join(`
|
|
6
|
+
|
|
7
|
+
`)))},{default:l(()=>[...a[20]||(a[20]=[u(" 复制 ",-1)])]),_:1})]),i("pre",He,r(t.value.response.client_stream_frames.join(`
|
|
8
|
+
|
|
9
|
+
`)),1)]),_:1},8,["label"])):E("",!0)],64)):(d(),g(H,{key:1},[e(C,{label:"请求体",name:"request"},{default:l(()=>[i("div",Qe,[e(f,{size:"small",class:"copy-btn",onClick:a[8]||(a[8]=w=>y(p(S)(t.value.request)))},{default:l(()=>[...a[21]||(a[21]=[u(" 复制 ",-1)])]),_:1})]),i("pre",Xe,r(p(S)(t.value.request)),1)]),_:1}),e(C,{label:"响应体",name:"response"},{default:l(()=>[i("div",Ze,[e(f,{size:"small",class:"copy-btn",onClick:a[9]||(a[9]=w=>y(p(S)(t.value.response)))},{default:l(()=>[...a[22]||(a[22]=[u(" 复制 ",-1)])]),_:1})]),i("pre",et,r(p(S)(t.value.response)),1)]),_:1})],64))]}),_:1},8,["modelValue"])])):E("",!0)]),_:1},8,["modelValue"])}}}),lt=ne(tt,[["__scopeId","data-v-ba28eb07"]]);function at(P){if(P.truncated!==!0)return null;const h=P.scanLimit;return`结果可能不完整:${typeof h=="number"&&Number.isFinite(h)&&h>0?`仅扫描了最近 ${h} 条有详情的记录`:"仅扫描了最近的部分记录"},建议缩小时间范围或更换关键词`}function st(P,h){const V=P.trim();return h>0||V.length!==1?null:"未找到匹配记录:单字符关键字仅按摘要列(模型、路径等)匹配,不会回退搜索请求/响应内容,建议补充至 2 个字符以上"}const ot={class:"logs-page"},nt={class:"filter-bar"},rt={class:"table-wrap"},ut=["onClick"],it={key:1},dt={class:"pagination-bar"},pt=ae({__name:"LogsView",setup(P){const h=De(),{toast:V}=re(),{loadError:M,run:X}=ue(),q=m(""),t=m(null),z=m("2xx"),R=m("model"),U=m(""),j=m(""),F=m([]),y=m(0),L=m(1),B=m(50),c=m(!1),a=m(null),f=m(null),A=o=>{var s;(s=f.value)==null||s.open(o)},b=he(()=>{const o=new Set;for(const s of h.suppliers)for(const v of s.models)o.add(v.modelName);for(const s of F.value)s.model&&o.add(s.model);return[...o].sort()}),Z=async o=>{await ie(o)?V("已复制到剪贴板","success"):V("复制失败","error")},W=o=>{const s=v=>String(v).padStart(2,"0");return`${o.getFullYear()}-${s(o.getMonth()+1)}-${s(o.getDate())}`},K=o=>{q.value=o;const s=new Date,v=new Date(s);if(o==="today")v.setDate(s.getDate());else if(o==="yesterday")v.setDate(s.getDate()-1),s.setDate(s.getDate()-1);else if(o==="beforeYesterday")v.setDate(s.getDate()-2),s.setDate(s.getDate()-2);else if(o==="last3days")v.setDate(s.getDate()-2);else if(o==="week"){const T=(s.getDay()+6)%7;v.setDate(s.getDate()-T)}else v.setDate(1);t.value=[W(v),W(s)],$()},ee=o=>{o?K(o):(q.value="",t.value=null,$())},C=o=>{q.value="",t.value=o||null,$()},G=()=>{const o={};return t.value&&t.value.length===2&&(o.startDate=t.value[0],o.endDate=t.value[1]),z.value&&(o.status=z.value),R.value&&(o.pathGroup=R.value),U.value&&(o.model=U.value),j.value&&(o.keyword=j.value),o},te=Ve(),N=()=>X(async()=>{const o=te();c.value=!0;try{const s={...G(),page:String(L.value),pageSize:String(B.value),sort:"time",order:"desc"},v=new URLSearchParams(s).toString(),T=await Q.get("/api/logs?"+v);if(!o())return;F.value=T.items||[],y.value=T.total||0,a.value=at(T)??st(j.value,T.total||0)}catch(s){if(!o())return;throw s}finally{o()&&(c.value=!1)}}),D=m(!1),J=async()=>{if(!(D.value||y.value===0)){try{await Ce.confirm(`将永久清理当前筛选条件下的 ${y.value} 条日志,清理后不可恢复,请谨慎操作!`,"清理确认",{confirmButtonText:"确认清理",cancelButtonText:"取消",type:"warning"})}catch{return}D.value=!0;try{const o=new URLSearchParams(G()).toString(),s=await Q.post("/api/logs/clear?"+o,{});V(`已清理 ${s.deleted??0} 条日志`,"success"),L.value>1&&(L.value=1),N()}catch(o){V(o.message||"清理失败","error")}finally{D.value=!1}}},$=()=>{L.value=1,N()},w=()=>{q.value="today",t.value=null,z.value="2xx",R.value="model",U.value="",j.value="",L.value=1,B.value=50,K("today")};return ke(()=>{h.loadProviders().catch(()=>{}),K("today")}),(o,s)=>{const v=_("el-button"),T=_("el-alert"),k=_("el-option"),O=_("el-select"),_e=_("el-date-picker"),ve=_("el-input"),le=_("el-card"),I=_("el-table-column"),me=_("el-tag"),fe=_("el-table"),be=_("el-pagination"),ge=se("loading");return d(),g("div",ot,[p(M)?(d(),x(T,{key:0,title:p(M),type:"error","show-icon":"",closable:!1,class:"mb-16"},{default:l(()=>[e(v,{size:"small",onClick:N},{default:l(()=>[...s[9]||(s[9]=[u("重试",-1)])]),_:1})]),_:1},8,["title"])):E("",!0),a.value?(d(),x(T,{key:1,title:a.value,type:"warning","show-icon":"",closable:"",class:"mb-16",onClose:s[0]||(s[0]=n=>a.value=null)},null,8,["title"])):E("",!0),e(le,{shadow:"never"},{default:l(()=>[i("div",nt,[e(O,{modelValue:q.value,"onUpdate:modelValue":s[1]||(s[1]=n=>q.value=n),placeholder:"时间范围",clearable:"",style:{width:"130px"},onChange:ee},{default:l(()=>[e(k,{label:"今天",value:"today"}),e(k,{label:"昨天",value:"yesterday"}),e(k,{label:"前天",value:"beforeYesterday"}),e(k,{label:"近三天",value:"last3days"}),e(k,{label:"本周",value:"week"}),e(k,{label:"本月",value:"month"})]),_:1},8,["modelValue"]),e(_e,{modelValue:t.value,"onUpdate:modelValue":s[2]||(s[2]=n=>t.value=n),type:"daterange","value-format":"YYYY-MM-DD","range-separator":"至","start-placeholder":"开始日期","end-placeholder":"结束日期",style:{width:"260px"},onChange:C},null,8,["modelValue"]),e(O,{modelValue:z.value,"onUpdate:modelValue":s[3]||(s[3]=n=>z.value=n),placeholder:"全部状态",clearable:"",style:{width:"120px"},onChange:$},{default:l(()=>[e(k,{label:"成功 (2xx)",value:"2xx"}),e(k,{label:"3xx",value:"3xx"}),e(k,{label:"4xx",value:"4xx"}),e(k,{label:"5xx",value:"5xx"}),e(k,{label:"错误 (4xx+)",value:"err"})]),_:1},8,["modelValue"]),e(O,{modelValue:R.value,"onUpdate:modelValue":s[4]||(s[4]=n=>R.value=n),placeholder:"全部路径",clearable:"",style:{width:"130px"},onChange:$},{default:l(()=>[e(k,{label:"模型接口",value:"model"}),e(k,{label:"其他",value:"other"})]),_:1},8,["modelValue"]),e(O,{modelValue:U.value,"onUpdate:modelValue":s[5]||(s[5]=n=>U.value=n),placeholder:"全部模型",clearable:"",filterable:"",style:{width:"220px"},onChange:$},{default:l(()=>[(d(!0),g(H,null,we(b.value,n=>(d(),x(k,{key:n,label:n,value:n},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),e(ve,{modelValue:j.value,"onUpdate:modelValue":s[6]||(s[6]=n=>j.value=n),class:"keyword-input",placeholder:"关键字搜索(请求/响应内容)",clearable:"",onKeyup:xe($,["enter"])},null,8,["modelValue"]),e(v,{type:"primary",class:"push-right",onClick:$},{default:l(()=>[...s[10]||(s[10]=[u("搜索",-1)])]),_:1}),e(v,{onClick:w},{default:l(()=>[...s[11]||(s[11]=[u("重置",-1)])]),_:1})])]),_:1}),e(le,{shadow:"never",class:"mt-16 table-card"},{default:l(()=>[i("div",rt,[oe((d(),x(fe,{data:F.value,border:"",stripe:"",height:"100%"},{default:l(()=>[e(I,{prop:"request_id",label:"请求ID","min-width":"140"},{default:l(({row:n})=>[n.request_id?(d(),g("span",{key:0,class:"request-id",title:"点击复制(可用于关联控制台日志与检索)",onClick:ye=>Z(n.request_id)},r(n.request_id),9,ut)):(d(),g("span",it,"-"))]),_:1}),e(I,{prop:"time",label:"时间",width:"180"},{default:l(({row:n})=>[u(r(p(de)(n.time)),1)]),_:1}),e(I,{prop:"model",label:"模型","min-width":"180"}),e(I,{prop:"status",label:"状态",width:"70",align:"center"},{default:l(({row:n})=>[e(me,{type:n.status>=400?"danger":n.status>=300?"warning":"success"},{default:l(()=>[u(r(n.status),1)]),_:2},1032,["type"])]),_:1}),e(I,{label:"输入",width:"110",align:"center"},{default:l(({row:n})=>[u(r(p(Y)(n.input_tokens??0)),1)]),_:1}),e(I,{label:"输出",width:"110",align:"center"},{default:l(({row:n})=>[u(r(p(Y)(n.output_tokens??0)),1)]),_:1}),e(I,{label:"缓存读取",width:"90",align:"center"},{default:l(({row:n})=>[u(r(p(Y)(n.cache_read_tokens??0)),1)]),_:1}),e(I,{label:"缓存命中率",width:"105",align:"center"},{default:l(({row:n})=>[i("span",null,r(p(ce)(n)),1)]),_:1}),e(I,{label:"请求耗时",width:"90",align:"center"},{default:l(({row:n})=>[u(r(p(pe)(n.duration)),1)]),_:1}),e(I,{label:"详情",width:"70",align:"center"},{default:l(({row:n})=>[e(v,{link:"",type:"primary",onClick:ye=>A(n)},{default:l(()=>[...s[12]||(s[12]=[u("查看",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"])),[[ge,c.value]])]),i("div",dt,[e(v,{type:"danger",plain:"",size:"small",loading:D.value,disabled:y.value===0,onClick:J},{default:l(()=>[...s[13]||(s[13]=[u("清理已筛选日志",-1)])]),_:1},8,["loading","disabled"]),e(be,{class:"push-right","current-page":L.value,"onUpdate:currentPage":s[7]||(s[7]=n=>L.value=n),"page-size":B.value,"onUpdate:pageSize":s[8]||(s[8]=n=>B.value=n),total:y.value,"page-sizes":[20,50,100,200],layout:"total, sizes, prev, pager, next",onCurrentChange:N,onSizeChange:N},null,8,["current-page","page-size","total"])])]),_:1}),e(lt,{ref_key:"logDetailRef",ref:f},null,512)])}}}),yt=ne(pt,[["__scopeId","data-v-5b05299d"]]);export{yt as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@charset "UTF-8";.provider-card[data-v-e96d8595]{min-width:0;cursor:grab;transition:box-shadow .2s,border-color .2s}.provider-card[data-v-e96d8595] .el-card__header{padding-bottom:10px}.provider-card[data-v-e96d8595] .el-card__body{padding-top:12px}.provider-card[data-v-e96d8595]:hover{border-color:#b1d2ff;box-shadow:0 4px 16px #3b82f61a}.provider-card.dragging[data-v-e96d8595]{cursor:grabbing}.card-header[data-v-e96d8595]{display:flex;justify-content:space-between;align-items:center;gap:12px}.card-title[data-v-e96d8595]{display:flex;align-items:center;gap:8px;min-width:0}.provider-name[data-v-e96d8595]{font-size:15px;font-weight:600;color:#303133;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.card-actions[data-v-e96d8595]{display:flex;gap:0;flex-shrink:0;cursor:auto}.card-meta[data-v-e96d8595]{display:flex;flex-direction:column;gap:6px;padding:0}.meta-row[data-v-e96d8595]{display:flex;align-items:center;gap:10px;font-size:13px;line-height:20px}.meta-label[data-v-e96d8595]{flex-shrink:0;width:60px;color:#909399}.meta-value[data-v-e96d8595]{flex:1;min-width:0;color:#606266;font-family:ui-monospace,SF Mono,Consolas,monospace;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.model-tags[data-v-e96d8595]{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}.model-tag[data-v-e96d8595]{display:inline-flex;align-items:center;max-width:100%;padding:3px 10px;font-size:12px;line-height:18px;color:#606266;background:#f5f7fa;border:1px solid transparent;border-radius:999px;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:color .15s,background .15s}.model-tag[data-v-e96d8595]:hover{color:#3b82f6;background:#eff6ff}.model-tag.ok[data-v-e96d8595]{color:#16a34a;background:#f0fdf4}.model-tag.error[data-v-e96d8595]{color:#dc2626;background:#fef2f2}.badge-mark[data-v-e96d8595]{margin-left:3px}.card-footer[data-v-e96d8595]{display:flex;justify-content:space-between;align-items:center;margin-top:14px;padding-top:12px;border-top:1px solid #f0f2f5}.model-count[data-v-e96d8595]{font-size:13px;color:#16a34a;font-weight:500;cursor:pointer;border-radius:4px}.model-count[data-v-e96d8595]:hover{text-decoration:underline}.drag-hint-icon[data-v-e96d8595]{flex-shrink:0;color:#c0c4cc;cursor:grab}.drag-hint-icon[data-v-e96d8595]:hover{color:#909399}.detail-body[data-v-08dfa117]{max-height:70vh;overflow-y:auto}.detail-head[data-v-08dfa117]{display:flex;align-items:center;gap:12px;margin-bottom:12px}.detail-name[data-v-08dfa117]{font-weight:600;font-size:14px}.detail-pre[data-v-08dfa117]{background:#f5f7fa;border:1px solid #e4e7ed;border-radius:6px;padding:12px;font-size:12px;line-height:1.6;color:#303133;max-height:300px;overflow:auto;margin:0;white-space:pre-wrap;word-break:break-all}.protocol-help .help-intro[data-v-2248b61a]{font-size:13px;color:#606266;margin-bottom:14px}.protocol-help .help-item[data-v-2248b61a]{margin-bottom:12px}.protocol-help .help-title[data-v-2248b61a]{font-weight:600;font-size:14px;color:#303133;margin-bottom:4px;display:flex;align-items:center;gap:8px}.protocol-help .help-item p[data-v-2248b61a]{font-size:13px;color:#606266;line-height:1.7;margin:0}.protocol-help .help-table-note[data-v-2248b61a]{margin-bottom:8px}.protocol-help .help-table[data-v-2248b61a]{width:100%}.model-select-wrap[data-v-cd73a0be]{width:400px;flex-shrink:0}.test-result-link[data-v-cd73a0be]{font-size:12px}.col-help[data-v-cd73a0be]{margin-right:4px}.col-help-icon[data-v-cd73a0be]{color:#c0c4cc;cursor:help;vertical-align:-2px}.col-help-icon[data-v-cd73a0be]:hover{color:#909399}.dialog-body[data-v-05bf13ed]{max-height:80vh;overflow-y:auto;overflow-x:hidden;padding-bottom:100px}.test-ok-text[data-v-05bf13ed]{font-size:12px;color:#16a34a;max-width:140px;display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle}.test-fail-text[data-v-05bf13ed]{font-size:12px;color:#dc2626;max-width:140px;display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle}.model-select-wrap[data-v-05bf13ed]{width:400px;flex-shrink:0}.protocol-hint[data-v-05bf13ed]{line-height:1.8}.label-action-btn[data-v-05bf13ed]{margin-left:8px;font-size:12px;height:auto}.label-inline-toggle[data-v-05bf13ed]{margin-left:8px;display:inline-flex;align-items:center;gap:6px}.test-result-link[data-v-05bf13ed]{font-size:12px}.col-help[data-v-05bf13ed]{margin-right:4px}.col-help-icon[data-v-05bf13ed]{color:#c0c4cc;cursor:help;vertical-align:-2px}.col-help-icon[data-v-05bf13ed]:hover{color:#909399}.models-dialog-body[data-v-a79f8c7b]{display:flex;flex-direction:column;height:calc(94vh - 100px)}.models-dialog-body .models-table[data-v-a79f8c7b]{flex:1;min-height:0}.error-tag[data-v-a79f8c7b]{max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ghost[data-v-f3ad9421]{opacity:.4}.provider-grid[data-v-f3ad9421]{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}@media(max-width:992px){.provider-grid[data-v-f3ad9421]{grid-template-columns:1fr}}
|