mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
3 lines
13 KiB
JavaScript
3 lines
13 KiB
JavaScript
import{E as le,a as ne,b as de,c as ie,d as ce}from"./element-plus-BUfCkBQO.js";import{b as F}from"./vendor-Dr8jvgFu.js";import{c as U,aW as ue,r as b,_ as z,o as L,q as ge,x as i,z as e,R as g,P as r,u as p,J as h,O as I,Q as $,ac as O,aU as pe,y as d,I as A}from"./vue-vendor-R8HMg95E.js";import{c as J,s as Y}from"./index-B3t2NHq9.js";import{f as x,R as xe}from"./RecordDetailModal-CIaCpUK_.js";const ye={class:"space-y-4 p-4 lg:p-6"},me={class:"flex flex-wrap items-center justify-between gap-3"},ke={class:"flex items-center gap-3"},fe={class:"text-xl font-bold text-gray-900 dark:text-gray-100"},_e={class:"text-xs text-gray-500 dark:text-gray-400"},ve={class:"flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400"},be={key:0},he={key:1},we={class:"grid gap-3 md:grid-cols-2 xl:grid-cols-4"},Re={class:"rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900"},Te={class:"mt-1 text-2xl font-bold text-gray-900 dark:text-gray-100"},Ce={class:"rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900"},Ie={class:"mt-1 text-2xl font-bold text-gray-900 dark:text-gray-100"},De={class:"rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900"},Se={class:"mt-1 text-2xl font-bold text-yellow-600 dark:text-yellow-400"},Pe={class:"rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900"},Ve={class:"mt-1 text-2xl font-bold text-gray-900 dark:text-gray-100"},ze={class:"rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900"},$e={class:"flex flex-wrap items-center gap-3"},Oe={class:"rounded-xl border border-gray-200 bg-white shadow-sm dark:border-gray-800 dark:bg-gray-900"},Ye={key:0,class:"flex items-center justify-center p-10 text-gray-500 dark:text-gray-400"},Ne={key:1},je={key:0,class:"flex flex-col items-center gap-2 p-10 text-gray-500 dark:text-gray-400"},Ee={key:1,class:"space-y-4"},Fe={class:"hidden overflow-x-auto md:block"},Ue={class:"min-w-full divide-y divide-gray-200 dark:divide-gray-800"},Me={class:"divide-y divide-gray-200 bg-white dark:divide-gray-800 dark:bg-gray-900"},Be={class:"whitespace-nowrap px-4 py-3 text-sm text-gray-800 dark:text-gray-100"},He={class:"px-4 py-3 text-sm text-gray-800 dark:text-gray-100"},Ke={class:"flex flex-col"},qe={class:"font-semibold"},Le={class:"text-xs text-gray-500 dark:text-gray-400"},Ae={class:"whitespace-nowrap px-4 py-3 text-sm text-gray-800 dark:text-gray-100"},Je={class:"whitespace-nowrap px-4 py-3 text-sm text-blue-600 dark:text-blue-400"},Qe={class:"whitespace-nowrap px-4 py-3 text-sm text-green-600 dark:text-green-400"},We={class:"whitespace-nowrap px-4 py-3 text-sm text-purple-600 dark:text-purple-400"},Ze={class:"whitespace-nowrap px-4 py-3 text-sm text-gray-800 dark:text-gray-100"},Ge={class:"whitespace-nowrap px-4 py-3 text-sm text-yellow-600 dark:text-yellow-400"},Xe={class:"whitespace-nowrap px-4 py-3 text-right text-sm"},et={class:"space-y-3 md:hidden"},tt={class:"flex items-center justify-between"},at={class:"text-sm font-semibold text-gray-900 dark:text-gray-100"},st={class:"text-xs text-gray-500 dark:text-gray-400"},ot={class:"mt-3 grid grid-cols-2 gap-2 text-sm text-gray-700 dark:text-gray-300"},rt={class:"text-yellow-600 dark:text-yellow-400"},lt={class:"flex items-center justify-between px-4 pb-4"},nt={class:"text-sm text-gray-500 dark:text-gray-400"},xt={__name:"ApiKeyUsageRecordsView",setup(dt){const Q=ue(),W=pe(),_=U(()=>Q.params.keyId),N=b(!1),D=b(!1),S=b([]),M=b([]),B=b([]),n=z({currentPage:1,pageSize:50,totalRecords:0}),s=z({dateRange:null,model:"",accountId:"",sortOrder:"desc"}),y=z({totalRequests:0,totalTokens:0,totalCost:0,avgCost:0}),P=z({id:_.value,name:""}),j=b(!1),E=b(null),Z=U(()=>P.name||P.id||_.value),H=U(()=>!s.dateRange||s.dateRange.length!==2?"":`${T(s.dateRange[0])} ~ ${T(s.dateRange[1])}`),T=o=>o?F(o).format("YYYY-MM-DD HH:mm:ss"):"--",C=o=>{const t=typeof o=="number"?o:0;return t>=1?`$${t.toFixed(2)}`:t>=.001?`$${t.toFixed(4)}`:`$${t.toFixed(6)}`},K=o=>{const t={page:o,pageSize:n.pageSize,sortOrder:s.sortOrder};return s.model&&(t.model=s.model),s.accountId&&(t.accountId=s.accountId),s.dateRange&&s.dateRange.length===2&&(t.startDate=F(s.dateRange[0]).toISOString(),t.endDate=F(s.dateRange[1]).toISOString()),t},G=o=>{var m,k,v,a;S.value=o.records||[];const t=o.pagination||{};n.currentPage=t.currentPage||1,n.pageSize=t.pageSize||n.pageSize,n.totalRecords=t.totalRecords||0;const l=o.filters||{};if(l.model!==void 0&&(s.model=l.model||""),l.accountId!==void 0&&(s.accountId=l.accountId||""),l.sortOrder&&(s.sortOrder=l.sortOrder),l.startDate&&l.endDate){const f=[l.startDate,l.endDate],R=s.dateRange||[];(R[0]!==f[0]||R[1]!==f[1])&&(s.dateRange=f)}const c=o.summary||{};y.totalRequests=c.totalRequests||0,y.totalTokens=c.totalTokens||0,y.totalCost=c.totalCost||0,y.avgCost=c.avgCost||0,P.id=((m=o.apiKeyInfo)==null?void 0:m.id)||_.value,P.name=((k=o.apiKeyInfo)==null?void 0:k.name)||"",M.value=((v=o.availableFilters)==null?void 0:v.models)||[],B.value=((a=o.availableFilters)==null?void 0:a.accounts)||[]},w=async(o=n.currentPage)=>{N.value=!0;try{const t=await J.get(`/admin/api-keys/${_.value}/usage-records`,{params:K(o)});G(t.data||{})}catch(t){Y(`加载请求记录失败:${t.message||"未知错误"}`,"error")}finally{N.value=!1}},X=o=>{n.currentPage=o,w(o)},ee=o=>{n.pageSize=o,n.currentPage=1,w(1)},te=()=>{s.model="",s.accountId="",s.dateRange=null,s.sortOrder="desc",n.currentPage=1,w(1)},q=o=>{E.value=o,j.value=!0},ae=()=>{j.value=!1,E.value=null},se=()=>{W.push("/api-keys")},oe=async()=>{var o;if(!D.value){D.value=!0;try{const t=[];let l=1,c=1;const m=50;for(;l<=c&&l<=m;){const V=(await J.get(`/admin/api-keys/${_.value}/usage-records`,{params:{...K(l),pageSize:200}})).data||{};t.push(...V.records||[]),c=((o=V.pagination)==null?void 0:o.totalPages)||1,l+=1}if(t.length===0){Y("没有可导出的记录","info");return}const v=[["时间","账户","渠道","模型","输入Token","输出Token","缓存创建Token","缓存读取Token","总Token","费用"].join(",")];t.forEach(u=>{const V=[T(u.timestamp),u.accountName||"",u.accountTypeName||"",u.model||"",u.inputTokens||0,u.outputTokens||0,u.cacheCreateTokens||0,u.cacheReadTokens||0,u.totalTokens||0,u.costFormatted||C(u.cost)];v.push(V.map(re=>`"${String(re).replace(/"/g,'""')}"`).join(","))});const a=new Blob([v.join(`
|
||
`)],{type:"text/csv;charset=utf-8;"}),f=URL.createObjectURL(a),R=document.createElement("a");R.href=f,R.download=`api-key-${_.value}-usage-records.csv`,R.click(),URL.revokeObjectURL(f),Y("导出 CSV 成功","success")}catch(t){Y(`导出失败:${t.message||"未知错误"}`,"error")}finally{D.value=!1}}};return L(()=>[s.model,s.accountId,s.sortOrder],()=>{n.currentPage=1,w(1)}),L(()=>s.dateRange,()=>{n.currentPage=1,w(1)},{deep:!0}),ge(()=>{w()}),(o,t)=>{const l=le,c=ce,m=ne,k=de,v=ie;return d(),i("div",ye,[e("div",me,[e("div",ke,[e("button",{class:"rounded-full border border-gray-200 px-3 py-2 text-sm text-gray-700 transition hover:bg-gray-100 dark:border-gray-700 dark:text-gray-200 dark:hover:bg-gray-800",onClick:se}," ← 返回 "),e("div",null,[t[4]||(t[4]=e("p",{class:"text-xs font-semibold uppercase tracking-wide text-blue-600 dark:text-blue-400"}," API Key 请求详情时间线 ",-1)),e("h2",fe,r(Z.value),1),e("p",_e,"ID: "+r(_.value),1)])]),e("div",ve,[t[5]||(t[5]=e("i",{class:"fas fa-clock text-blue-500"},null,-1)),H.value?(d(),i("span",be,r(H.value),1)):(d(),i("span",he,"显示近 5000 条记录"))])]),e("div",we,[e("div",Re,[t[6]||(t[6]=e("p",{class:"text-xs uppercase text-gray-500 dark:text-gray-400"},"总请求",-1)),e("p",Te,r(p(x)(y.totalRequests)),1)]),e("div",Ce,[t[7]||(t[7]=e("p",{class:"text-xs uppercase text-gray-500 dark:text-gray-400"},"总 Token",-1)),e("p",Ie,r(p(x)(y.totalTokens)),1)]),e("div",De,[t[8]||(t[8]=e("p",{class:"text-xs uppercase text-gray-500 dark:text-gray-400"},"总费用",-1)),e("p",Se,r(C(y.totalCost)),1)]),e("div",Pe,[t[9]||(t[9]=e("p",{class:"text-xs uppercase text-gray-500 dark:text-gray-400"},"平均费用/次",-1)),e("p",Ve,r(C(y.avgCost)),1)])]),e("div",ze,[e("div",$e,[g(l,{modelValue:s.dateRange,"onUpdate:modelValue":t[0]||(t[0]=a=>s.dateRange=a),class:"max-w-[320px]",clearable:"","end-placeholder":"结束时间",format:"YYYY-MM-DD HH:mm:ss","start-placeholder":"开始时间",type:"datetimerange","unlink-panels":"","value-format":"YYYY-MM-DDTHH:mm:ss[Z]"},null,8,["modelValue"]),g(m,{modelValue:s.model,"onUpdate:modelValue":t[1]||(t[1]=a=>s.model=a),class:"w-[180px]",clearable:"",filterable:"",placeholder:"所有模型"},{default:h(()=>[(d(!0),i($,null,O(M.value,a=>(d(),A(c,{key:a,label:a,value:a},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),g(m,{modelValue:s.accountId,"onUpdate:modelValue":t[2]||(t[2]=a=>s.accountId=a),class:"w-[220px]",clearable:"",filterable:"",placeholder:"所有账户"},{default:h(()=>[(d(!0),i($,null,O(B.value,a=>(d(),A(c,{key:a.id,label:`${a.name}(${a.accountTypeName})`,value:a.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),g(m,{modelValue:s.sortOrder,"onUpdate:modelValue":t[3]||(t[3]=a=>s.sortOrder=a),class:"w-[140px]",placeholder:"排序"},{default:h(()=>[g(c,{label:"时间降序",value:"desc"}),g(c,{label:"时间升序",value:"asc"})]),_:1},8,["modelValue"]),g(k,{onClick:te},{default:h(()=>t[10]||(t[10]=[e("i",{class:"fas fa-undo mr-2"},null,-1),I(" 重置 ",-1)])),_:1,__:[10]}),g(k,{loading:D.value,type:"primary",onClick:oe},{default:h(()=>t[11]||(t[11]=[e("i",{class:"fas fa-file-export mr-2"},null,-1),I(" 导出 CSV ",-1)])),_:1,__:[11]},8,["loading"])])]),e("div",Oe,[N.value?(d(),i("div",Ye,t[12]||(t[12]=[e("i",{class:"fas fa-spinner fa-spin mr-2"},null,-1),I(" 加载中... ",-1)]))):(d(),i("div",Ne,[S.value.length===0?(d(),i("div",je,t[13]||(t[13]=[e("i",{class:"fas fa-inbox text-2xl"},null,-1),e("p",null,"暂无记录",-1)]))):(d(),i("div",Ee,[e("div",Fe,[e("table",Ue,[t[15]||(t[15]=e("thead",{class:"bg-gray-50 dark:bg-gray-800"},[e("tr",null,[e("th",{class:"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 时间 "),e("th",{class:"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 账户 "),e("th",{class:"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 模型 "),e("th",{class:"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 输入 "),e("th",{class:"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 输出 "),e("th",{class:"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 缓存(创/读) "),e("th",{class:"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 总 Token "),e("th",{class:"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 费用 "),e("th",{class:"px-4 py-3 text-right text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300"}," 操作 ")])],-1)),e("tbody",Me,[(d(!0),i($,null,O(S.value,a=>(d(),i("tr",{key:a.timestamp+a.model},[e("td",Be,r(T(a.timestamp)),1),e("td",He,[e("div",Ke,[e("span",qe,r(a.accountName||"未知账户"),1),e("span",Le,r(a.accountTypeName||"未知渠道"),1)])]),e("td",Ae,r(a.model),1),e("td",Je,r(p(x)(a.inputTokens)),1),e("td",Qe,r(p(x)(a.outputTokens)),1),e("td",We,r(p(x)(a.cacheCreateTokens))+" / "+r(p(x)(a.cacheReadTokens)),1),e("td",Ze,r(p(x)(a.totalTokens)),1),e("td",Ge,r(a.costFormatted||C(a.cost)),1),e("td",Xe,[g(k,{size:"small",onClick:f=>q(a)},{default:h(()=>t[14]||(t[14]=[I("详情",-1)])),_:2,__:[14]},1032,["onClick"])])]))),128))])])]),e("div",et,[(d(!0),i($,null,O(S.value,a=>(d(),i("div",{key:a.timestamp+a.model,class:"rounded-lg border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900"},[e("div",tt,[e("div",null,[e("p",at,r(a.accountName||"未知账户"),1),e("p",st,r(T(a.timestamp)),1)]),g(k,{size:"small",onClick:f=>q(a)},{default:h(()=>t[16]||(t[16]=[I("详情",-1)])),_:2,__:[16]},1032,["onClick"])]),e("div",ot,[e("div",null,"模型:"+r(a.model),1),e("div",null,"总 Token:"+r(p(x)(a.totalTokens)),1),e("div",null,"输入:"+r(p(x)(a.inputTokens)),1),e("div",null,"输出:"+r(p(x)(a.outputTokens)),1),e("div",null," 缓存创/读:"+r(p(x)(a.cacheCreateTokens))+" / "+r(p(x)(a.cacheReadTokens)),1),e("div",rt," 费用:"+r(a.costFormatted||C(a.cost)),1)])]))),128))]),e("div",lt,[e("div",nt," 共 "+r(n.totalRecords)+" 条记录 ",1),g(v,{background:"","current-page":n.currentPage,layout:"prev, pager, next, sizes","page-size":n.pageSize,"page-sizes":[20,50,100,200],total:n.totalRecords,onCurrentChange:X,onSizeChange:ee},null,8,["current-page","page-size","total"])])]))]))]),g(xe,{record:E.value,show:j.value,onClose:ae},null,8,["record","show"])])}}};export{xt as default};
|