import{ae as Da,a3 as Je,af as ra,X as la,U as Ee,g as re,Q as va,ag as ua,z as Ma,Z as Ga,ah as Ka,e as Ie,w as pe,N as ja,h as ye,A as Ha,S as Wa,T as qa,$ as Xa,D as na,C as pa,ai as Za,aj as Qe,ak as sa,a4 as Ye,q as Oe,aa as Ja,ab as Qa,o as oe,al as Ya,ad as et,a as q,_ as at,E as tt,v as lt,a0 as nt,d as st,G as ze,H as Q}from"./index-xdc4dCJw.js";import{v as ot}from"./el-loading-C65vMcpP.js";import{E as it}from"./el-dialog-BA6jXtcD.js";import{E as rt,a as ut}from"./el-form-item-BeAZtehy.js";/* empty css */import{E as dt,a as ct}from"./el-switch-DqGKUJZv.js";import{E as ft}from"./el-pagination-TTFXkW0k.js";import{d as vt,r as pt,E as bt,a as mt,b as _t}from"./el-table-column-MgpB2mM7.js";import{c as ie,a as yt,E as ht}from"./el-select-C_Dn-Lrv.js";import{E as gt}from"./el-link-qY5gqqju.js";import{M as wt}from"./MetricGrid-BrU15hWW.js";import{b as kt,d as ea,F as Ct,G as St,H as da,I as Et,J as It,c as ca}from"./vendor-misc-vmXLPW1j.js";import{s as aa,v as H,a3 as Pt,al as Ae,d as Me,a1 as Tt,f as ta,r as y,i as Ge,e as B,x as W,y as V,B as T,R as fe,am as ba,u as o,M as De,I as Y,k as ma,z as he,$ as P,O as U,n as ge,P as _a,q as ya,a0 as ha,ab as Vt,w as ve,H as ga,a4 as wa,J as M,A as Rt,Q as ka,an as Nt,V as a,c as Ca,F as xt,ao as $t,G as Le,Z as Bt,K as n}from"./vendor-vue-CrWqv-BE.js";import"./vendor-axios-B9ygI19o.js";import"./refs-Cgn3sBur.js";import"./index-CvKMBPkw.js";const Ft=(t,s,r)=>Da(t.subTree).filter(d=>{var k;return Tt(d)&&((k=d.type)==null?void 0:k.name)===s&&!!d.component}).map(d=>d.component.uid).map(d=>r[d]).filter(d=>!!d),Ut=(t,s)=>{const r=aa({}),f=aa([]),i=new WeakMap,d=C=>{r.value[C.uid]=C,Ae(r),Me(()=>{const g=C.getVnode().el,c=g.parentNode;if(!i.has(c)){i.set(c,[]);const p=c.insertBefore.bind(c);c.insertBefore=(w,m)=>(i.get(c).some(O=>w===O||m===O)&&Ae(r),p(w,m))}i.get(c).push(g)})},k=C=>{delete r.value[C.uid],Ae(r);const g=C.getVnode().el,c=g.parentNode,p=i.get(c),w=p.indexOf(g);p.splice(w,1)},h=()=>{f.value=Ft(t,s,r.value)},v=C=>C.render(),_=H({setup(C,{slots:g}){return()=>(h(),g.default?Pt(v,{render:g.default}):null)}});return{children:f,addChild:d,removeChild:k,ChildrenSorter:_}},Sa=re({modelValue:{type:[String,Number,Boolean],default:void 0},size:va,disabled:Boolean,label:{type:[String,Number,Boolean],default:void 0},value:{type:[String,Number,Boolean],default:void 0},name:{type:String,default:void 0}}),zt=re({...Sa,border:Boolean}),Ea={[Ee]:t=>ta(t)||Je(t)||ra(t),[la]:t=>ta(t)||Je(t)||ra(t)},Ia=Symbol("radioGroupKey"),Pa=(t,s)=>{const r=y(),f=Ge(Ia,void 0),i=B(()=>!!f),d=B(()=>ua(t.value)?t.label:t.value),k=B({get(){return i.value?f.modelValue:t.modelValue},set(g){i.value?f.changeEvent(g):s&&s(Ee,g),r.value.checked=t.modelValue===d.value}}),h=Ma(B(()=>f?.size)),v=Ga(B(()=>f?.disabled)),_=y(!1),C=B(()=>v.value||i.value&&k.value!==d.value?-1:0);return Ka({from:"label act as value",replacement:"value",version:"3.0.0",scope:"el-radio",ref:"https://element-plus.org/en-US/component/radio.html"},B(()=>i.value&&ua(t.value))),{radioRef:r,isGroup:i,radioGroup:f,focus:_,size:h,disabled:v,tabIndex:C,modelValue:k,actualValue:d}},Ot=H({name:"ElRadio"}),At=H({...Ot,props:zt,emits:Ea,setup(t,{emit:s}){const r=t,f=pe("radio"),{radioRef:i,radioGroup:d,focus:k,size:h,disabled:v,modelValue:_,actualValue:C}=Pa(r,s);function g(){ge(()=>s(la,_.value))}return(c,p)=>{var w;return V(),W("label",{class:Y([o(f).b(),o(f).is("disabled",o(v)),o(f).is("focus",o(k)),o(f).is("bordered",c.border),o(f).is("checked",o(_)===o(C)),o(f).m(o(h))])},[T("span",{class:Y([o(f).e("input"),o(f).is("disabled",o(v)),o(f).is("checked",o(_)===o(C))])},[fe(T("input",{ref_key:"radioRef",ref:i,"onUpdate:modelValue":m=>ma(_)?_.value=m:null,class:Y(o(f).e("original")),value:o(C),name:c.name||((w=o(d))==null?void 0:w.name),disabled:o(v),checked:o(_)===o(C),type:"radio",onFocus:m=>k.value=!0,onBlur:m=>k.value=!1,onChange:g,onClick:De(()=>{},["stop"])},null,42,["onUpdate:modelValue","value","name","disabled","checked","onFocus","onBlur","onClick"]),[[ba,o(_)]]),T("span",{class:Y(o(f).e("inner"))},null,2)],2),T("span",{class:Y(o(f).e("label")),onKeydown:De(()=>{},["stop"])},[he(c.$slots,"default",{},()=>[P(U(c.label),1)])],42,["onKeydown"])],2)}}});var Ta=Ie(At,[["__file","radio.vue"]]);const Lt=re({...Sa}),Dt=H({name:"ElRadioButton"}),Mt=H({...Dt,props:Lt,setup(t){const s=t,r=pe("radio"),{radioRef:f,focus:i,size:d,disabled:k,modelValue:h,radioGroup:v,actualValue:_}=Pa(s),C=B(()=>({backgroundColor:v?.fill||"",borderColor:v?.fill||"",boxShadow:v?.fill?`-1px 0 0 0 ${v.fill}`:"",color:v?.textColor||""}));return(g,c)=>{var p;return V(),W("label",{class:Y([o(r).b("button"),o(r).is("active",o(h)===o(_)),o(r).is("disabled",o(k)),o(r).is("focus",o(i)),o(r).bm("button",o(d))])},[fe(T("input",{ref_key:"radioRef",ref:f,"onUpdate:modelValue":w=>ma(h)?h.value=w:null,class:Y(o(r).be("button","original-radio")),value:o(_),type:"radio",name:g.name||((p=o(v))==null?void 0:p.name),disabled:o(k),onFocus:w=>i.value=!0,onBlur:w=>i.value=!1,onClick:De(()=>{},["stop"])},null,42,["onUpdate:modelValue","value","name","disabled","onFocus","onBlur","onClick"]),[[ba,o(h)]]),T("span",{class:Y(o(r).be("button","inner")),style:_a(o(h)===o(_)?o(C):{}),onKeydown:De(()=>{},["stop"])},[he(g.$slots,"default",{},()=>[P(U(g.label),1)])],46,["onKeydown"])],2)}}});var Va=Ie(Mt,[["__file","radio-button.vue"]]);const Gt=re({id:{type:String,default:void 0},size:va,disabled:Boolean,modelValue:{type:[String,Number,Boolean],default:void 0},fill:{type:String,default:""},textColor:{type:String,default:""},name:{type:String,default:void 0},validateEvent:{type:Boolean,default:!0},options:{type:ye(Array)},props:{type:ye(Object),default:()=>Ra},...ja(["ariaLabel"])}),Kt=Ea,Ra={label:"label",value:"value",disabled:"disabled"},jt=H({name:"ElRadioGroup"}),Ht=H({...jt,props:Gt,emits:Kt,setup(t,{emit:s}){const r=t,f=pe("radio"),i=Ha(),d=y(),{formItem:k}=Wa(),{inputId:h,isLabeledByFormItem:v}=qa(r,{formItemContext:k}),_=p=>{s(Ee,p),ge(()=>s(la,p))};Me(()=>{const p=d.value.querySelectorAll("[type=radio]"),w=p[0];!Array.from(p).some(m=>m.checked)&&w&&(w.tabIndex=0)});const C=B(()=>r.name||i.value),g=B(()=>({...Ra,...r.props})),c=p=>{const w={label:p[g.value.label],value:p[g.value.value],disabled:p[g.value.disabled]};return{...p,...w}};return ya(Ia,ha({...Vt(r),changeEvent:_,name:C})),ve(()=>r.modelValue,(p,w)=>{r.validateEvent&&!kt(p,w)&&k?.validate("change").catch(m=>Xa())}),(p,w)=>(V(),W("div",{id:o(h),ref_key:"radioGroupRef",ref:d,class:Y(o(f).b("group")),role:"radiogroup","aria-label":o(v)?void 0:p.ariaLabel||"radio-group","aria-labelledby":o(v)?o(k).labelId:void 0},[he(p.$slots,"default",{},()=>[(V(!0),W(ga,null,wa(r.options,(m,S)=>(V(),M(Ta,Rt({key:S},c(m)),null,16))),128))])],10,["id","aria-label","aria-labelledby"]))}});var Na=Ie(Ht,[["__file","radio-group.vue"]]);pa(Ta,{RadioButton:Va,RadioGroup:Na});const Wt=na(Na),qt=na(Va),Xt="horizontal",Zt="vertical",Jt={[Xt]:"deltaX",[Zt]:"deltaY"},Qt=({atEndEdge:t,atStartEdge:s,layout:r},f)=>{let i,d=0;const k=v=>v<0&&s.value||v>0&&t.value;return{hasReachedEdge:k,onWheel:v=>{vt(i);const _=v[Jt[r.value]];k(d)&&k(d+_)||(d+=_,Za()||v.preventDefault(),i=pt(()=>{f(d),d=0}))}}},Ke=Symbol("tabsRootContextKey"),Yt=re({tabs:{type:ye(Array),default:()=>Qe([])},tabRefs:{type:ye(Object),default:()=>Qe({})}}),xa="ElTabBar",el=H({name:xa}),al=H({...el,props:Yt,setup(t,{expose:s}){const r=t,f=Ge(Ke);f||sa(xa,"");const i=pe("tabs"),d=y(),k=y(),h=()=>{let c=0,p=0;const w=["top","bottom"].includes(f.props.tabPosition)?"width":"height",m=w==="width"?"x":"y",S=m==="x"?"left":"top";return r.tabs.every(O=>{if(Ye(O.paneName))return!1;const b=r.tabRefs[O.paneName];if(!b)return!1;if(!O.active)return!0;c=b[`offset${ie(S)}`],p=b[`client${ie(w)}`];const A=window.getComputedStyle(b);return w==="width"&&(p-=Number.parseFloat(A.paddingLeft)+Number.parseFloat(A.paddingRight),c+=Number.parseFloat(A.paddingLeft)),!1}),{[w]:`${p}px`,transform:`translate${ie(m)}(${c}px)`}},v=()=>k.value=h(),_=[],C=()=>{_.forEach(c=>c.stop()),_.length=0,Object.values(r.tabRefs).forEach(c=>{_.push(ea(c,v))})};ve(()=>r.tabs,async()=>{await ge(),v(),C()},{immediate:!0});const g=ea(d,()=>v());return ka(()=>{_.forEach(c=>c.stop()),_.length=0,g.stop()}),s({ref:d,update:v}),(c,p)=>(V(),W("div",{ref_key:"barRef",ref:d,class:Y([o(i).e("active-bar"),o(i).is(o(f).props.tabPosition)]),style:_a(k.value)},null,6))}});var tl=Ie(al,[["__file","tab-bar.vue"]]);const ll=re({panes:{type:ye(Array),default:()=>Qe([])},currentName:{type:[String,Number],default:""},editable:Boolean,type:{type:String,values:["card","border-card",""],default:""},stretch:Boolean}),nl={tabClick:(t,s,r)=>r instanceof Event,tabRemove:(t,s)=>s instanceof Event},fa="ElTabNav",sl=H({name:fa,props:ll,emits:nl,setup(t,{expose:s,emit:r}){const f=Ge(Ke);f||sa(fa,"");const i=pe("tabs"),d=Ct(),k=St(),h=y(),v=y(),_=y(),C=y({}),g=y(),c=y(!1),p=y(0),w=y(!1),m=y(!0),S=aa(),O=B(()=>["top","bottom"].includes(f.props.tabPosition)),b=B(()=>O.value?"width":"height"),A=B(()=>({transform:`translate${b.value==="width"?"X":"Y"}(-${p.value}px)`})),{width:G,height:N}=da(h),{width:L,height:ae}=da(v,{width:0,height:0},{box:"border-box"}),X=B(()=>O.value?G.value:N.value),K=B(()=>O.value?L.value:ae.value),{onWheel:be}=Qt({atStartEdge:B(()=>p.value<=0),atEndEdge:B(()=>K.value-p.value<=X.value),layout:B(()=>O.value?"horizontal":"vertical")},I=>{p.value=Et(p.value+I,0,K.value-X.value)}),Pe=()=>{if(!h.value)return;const I=h.value[`offset${ie(b.value)}`],x=p.value;if(!x)return;const E=x>I?x-I:0;p.value=E},me=()=>{if(!h.value||!v.value)return;const I=v.value[`offset${ie(b.value)}`],x=h.value[`offset${ie(b.value)}`],E=p.value;if(I-E<=x)return;const $=I-E>x*2?E+x:I-x;p.value=$},Te=async()=>{const I=v.value;if(!c.value||!_.value||!h.value||!I)return;await ge();const x=C.value[t.currentName];if(!x)return;const E=h.value,$=x.getBoundingClientRect(),z=E.getBoundingClientRect(),de=O.value?I.offsetWidth-z.width:I.offsetHeight-z.height,Z=p.value;let j=Z;O.value?($.leftz.right&&(j=Z+$.right-z.right)):($.topz.bottom&&(j=Z+($.bottom-z.bottom))),j=Math.max(j,0),p.value=Math.min(j,de)},Ve=()=>{var I;if(!v.value||!h.value)return;t.stretch&&((I=g.value)==null||I.update());const x=v.value[`offset${ie(b.value)}`],E=h.value[`offset${ie(b.value)}`],$=p.value;E0&&(p.value=0))},je=I=>{let x=0;switch(I.code){case oe.left:case oe.up:x=-1;break;case oe.right:case oe.down:x=1;break;default:return}const E=Array.from(I.currentTarget.querySelectorAll("[role=tab]:not(.is-disabled)"));let z=E.indexOf(I.target)+x;z<0?z=E.length-1:z>=E.length&&(z=0),E[z].focus({preventScroll:!0}),E[z].click(),te()},te=()=>{m.value&&(w.value=!0)},le=()=>w.value=!1,ue=(I,x)=>{C.value[x]=I},Re=async()=>{await ge();const I=C.value[t.currentName];I?.focus({preventScroll:!0})};return ve(d,I=>{I==="hidden"?m.value=!1:I==="visible"&&setTimeout(()=>m.value=!0,50)}),ve(k,I=>{I?setTimeout(()=>m.value=!0,50):m.value=!1}),ea(_,Ve),Me(()=>setTimeout(()=>Te(),0)),Nt(()=>Ve()),s({scrollToActiveTab:Te,removeFocus:le,focusActiveTab:Re,tabListRef:v,tabBarRef:g,scheduleRender:()=>Ae(S)}),()=>{const I=c.value?[a("span",{class:[i.e("nav-prev"),i.is("disabled",!c.value.prev)],onClick:Pe},[a(Oe,null,{default:()=>[a(Ja,null,null)]})]),a("span",{class:[i.e("nav-next"),i.is("disabled",!c.value.next)],onClick:me},[a(Oe,null,{default:()=>[a(Qa,null,null)]})])]:null,x=t.panes.map((E,$)=>{var z,de,Z,j;const Ne=E.uid,ne=E.props.disabled,se=(de=(z=E.props.name)!=null?z:E.index)!=null?de:`${$}`,we=!ne&&(E.isClosable||E.props.closable!==!1&&t.editable);E.index=`${$}`;const He=we?a(Oe,{class:"is-icon-close",onClick:J=>r("tabRemove",E,J)},{default:()=>[a(Ya,null,null)]}):null,We=((j=(Z=E.slots).label)==null?void 0:j.call(Z))||E.props.label,ke=!ne&&E.active?0:-1;return a("div",{ref:J=>ue(J,se),class:[i.e("item"),i.is(f.props.tabPosition),i.is("active",E.active),i.is("disabled",ne),i.is("closable",we),i.is("focus",w.value)],id:`tab-${se}`,key:`tab-${Ne}`,"aria-controls":`pane-${se}`,role:"tab","aria-selected":E.active,tabindex:ke,onFocus:()=>te(),onBlur:()=>le(),onClick:J=>{le(),r("tabClick",E,se,J)},onKeydown:J=>{we&&(J.code===oe.delete||J.code===oe.backspace)&&r("tabRemove",E,J)}},[We,He])});return S.value,a("div",{ref:_,class:[i.e("nav-wrap"),i.is("scrollable",!!c.value),i.is(f.props.tabPosition)]},[I,a("div",{class:i.e("nav-scroll"),ref:h},[t.panes.length>0?a("div",{class:[i.e("nav"),i.is(f.props.tabPosition),i.is("stretch",t.stretch&&["top","bottom"].includes(f.props.tabPosition))],ref:v,style:A.value,role:"tablist",onKeydown:je,onWheel:be},[t.type?null:a(tl,{ref:g,tabs:[...t.panes],tabRefs:C.value},null),x]):null])])}}}),ol=re({type:{type:String,values:["card","border-card",""],default:""},closable:Boolean,addable:Boolean,modelValue:{type:[String,Number]},editable:Boolean,tabPosition:{type:String,values:["top","right","bottom","left"],default:"top"},beforeLeave:{type:ye(Function),default:()=>!0},stretch:Boolean}),Xe=t=>ta(t)||Je(t),il={[Ee]:t=>Xe(t),tabClick:(t,s)=>s instanceof Event,tabChange:t=>Xe(t),edit:(t,s)=>["remove","add"].includes(s),tabRemove:t=>Xe(t),tabAdd:()=>!0},rl=H({name:"ElTabs",props:ol,emits:il,setup(t,{emit:s,slots:r,expose:f}){var i;const d=pe("tabs"),k=B(()=>["left","right"].includes(t.tabPosition)),{children:h,addChild:v,removeChild:_,ChildrenSorter:C}=Ut(Ca(),"ElTabPane"),g=y(),c=y((i=t.modelValue)!=null?i:"0"),p=async(b,A=!1)=>{var G,N,L,ae;if(!(c.value===b||Ye(b)))try{let X;if(t.beforeLeave){const K=t.beforeLeave(b,c.value);X=K instanceof Promise?await K:K}else X=!0;if(X!==!1){const K=(G=h.value.find(be=>be.paneName===c.value))==null?void 0:G.isFocusInsidePane();c.value=b,A&&(s(Ee,b),s("tabChange",b)),(L=(N=g.value)==null?void 0:N.removeFocus)==null||L.call(N),K&&((ae=g.value)==null||ae.focusActiveTab())}}catch{}},w=(b,A,G)=>{b.props.disabled||(s("tabClick",b,G),p(A,!0))},m=(b,A)=>{b.props.disabled||Ye(b.props.name)||(A.stopPropagation(),s("edit",b.props.name,"remove"),s("tabRemove",b.props.name))},S=()=>{s("edit",void 0,"add"),s("tabAdd")},O=b=>{const A=b.el.firstChild,G=["bottom","right"].includes(t.tabPosition)?b.children[0].el:b.children[1].el;A!==G&&A.before(G)};return ve(()=>t.modelValue,b=>p(b)),ve(c,async()=>{var b;await ge(),(b=g.value)==null||b.scrollToActiveTab()}),ya(Ke,{props:t,currentName:c,registerPane:v,unregisterPane:_,nav$:g}),f({currentName:c,get tabNavRef(){return It(g.value,["scheduleRender"])}}),()=>{const b=r["add-icon"],A=t.editable||t.addable?a("div",{class:[d.e("new-tab"),k.value&&d.e("new-tab-vertical")],tabindex:"0",onClick:S,onKeydown:ae=>{[oe.enter,oe.numpadEnter].includes(ae.code)&&S()}},[b?he(r,"add-icon"):a(Oe,{class:d.is("icon-plus")},{default:()=>[a(et,null,null)]})]):null,G=()=>a(sl,{ref:g,currentName:c.value,editable:t.editable,type:t.type,panes:h.value,stretch:t.stretch,onTabClick:w,onTabRemove:m},null),N=a("div",{class:[d.e("header"),k.value&&d.e("header-vertical"),d.is(t.tabPosition)]},[a(C,null,{default:G,$stable:!0}),A]),L=a("div",{class:d.e("content")},[he(r,"default")]);return a("div",{class:[d.b(),d.m(t.tabPosition),{[d.m("card")]:t.type==="card",[d.m("border-card")]:t.type==="border-card"}],onVnodeMounted:O,onVnodeUpdated:O},[L,N])}}});var ul=rl;const dl=re({label:{type:String,default:""},name:{type:[String,Number]},closable:{type:Boolean,default:void 0},disabled:Boolean,lazy:Boolean}),$a="ElTabPane",cl=H({name:$a}),fl=H({...cl,props:dl,setup(t){const s=t,r=Ca(),f=xt(),i=Ge(Ke);i||sa($a,"usage: ");const d=pe("tab-pane"),k=y(),h=y(),v=B(()=>{var m;return(m=s.closable)!=null?m:i.props.closable}),_=ca(()=>{var m;return i.currentName.value===((m=s.name)!=null?m:h.value)}),C=y(_.value),g=B(()=>{var m;return(m=s.name)!=null?m:h.value}),c=ca(()=>!s.lazy||C.value||_.value),p=()=>{var m;return(m=k.value)==null?void 0:m.contains(document.activeElement)};ve(_,m=>{m&&(C.value=!0)});const w=ha({uid:r.uid,getVnode:()=>r.vnode,slots:f,props:s,paneName:g,active:_,index:h,isClosable:v,isFocusInsidePane:p});return i.registerPane(w),ka(()=>{i.unregisterPane(w)}),$t(()=>{var m;f.label&&((m=i.nav$.value)==null||m.scheduleRender())}),(m,S)=>o(c)?fe((V(),W("div",{key:0,id:`pane-${o(g)}`,ref_key:"paneRef",ref:k,class:Y(o(d).b()),role:"tabpanel","aria-hidden":!o(_),"aria-labelledby":`tab-${o(g)}`},[he(m.$slots,"default")],10,["id","aria-hidden","aria-labelledby"])),[[Bt,o(_)]]):Le("v-if",!0)}});var Ba=Ie(fl,[["__file","tab-pane.vue"]]);const vl=pa(ul,{TabPane:Ba}),pl=na(Ba);async function bl(){const{data:t}=await q.get("/admin/security/dashboard");return t}async function ml(t){const{data:s}=await q.get("/admin/security/threats",{params:t});return s}async function _l(){const{data:t}=await q.get("/admin/security/banned-ips");return t}async function yl(){const{data:t}=await q.get("/admin/security/banned-users");return t}async function hl(t){const{data:s}=await q.post("/admin/security/ban-ip",t);return s}async function gl(t){const{data:s}=await q.post("/admin/security/unban-ip",{ip:t});return s}async function wl(t){const{data:s}=await q.post("/admin/security/ban-user",t);return s}async function kl(t){const{data:s}=await q.post("/admin/security/unban-user",{user_id:t});return s}async function Cl(t){const s=encodeURIComponent(String(t||"").trim()),{data:r}=await q.get(`/admin/security/ip-risk/${s}`);return r}async function Sl(t){const{data:s}=await q.post("/admin/security/ip-risk/clear",{ip:t});return s}async function El(t){const s=encodeURIComponent(String(t||"").trim()),{data:r}=await q.get(`/admin/security/user-risk/${s}`);return r}async function Il(){const{data:t}=await q.post("/admin/security/cleanup",{});return t}const Pl={class:"page-stack"},Tl={class:"app-page-title"},Vl={class:"toolbar"},Rl={class:"filters"},Nl={class:"table-wrap"},xl={key:1},$l={key:1},Bl={class:"mono ellipsis"},Fl={class:"ellipsis"},Ul={class:"pagination"},zl={class:"page-hint app-muted"},Ol={class:"toolbar"},Al={class:"table-wrap"},Ll={class:"table-wrap"},Dl={class:"filters"},Ml={class:"filters"},Gl={class:"risk-head"},Kl={class:"risk-title"},jl={key:0},Hl={key:1},Wl={class:"toolbar"},ql={class:"table-wrap"},Xl={class:"mono ellipsis"},Zl={class:"ellipsis"},Jl={class:"dialog-actions"},Ze=20,Ql={__name:"SecurityPage",setup(t){const s=y("threats"),r=y(!1),f=y(null),i=y(!1),d=y([]),k=y(0),h=y(1),v=y(""),_=y(""),C=y(!1),g=y([]),c=y([]),p=y("ips"),w=y(!1),m=y(!1),S=y({kind:"ip",ip:"",user_id:"",reason:"",duration_hours:24,permanent:!1}),O=y("ip"),b=y(!1),A=y(""),G=y(""),N=y(null),L=y(""),ae=["sql_injection","xss","path_traversal","command_injection","ssrf","scanner","bruteforce","csrf","xxe","file_upload"];function X(u){const e=Number(u);return Number.isFinite(e)?e:0}function K(u){const e=Number(u||0);return e>=80?{label:"高",type:"danger"}:e>=50?{label:"中",type:"warning"}:{label:"低",type:"success"}}function be(u){const e=String(u||"").trim();return e||"永久"}function Pe(u){const e=[];return u?.field_name&&e.push(`字段: ${u.field_name}`),u?.rule&&e.push(`规则: ${u.rule}`),u?.matched&&e.push(`匹配: ${u.matched}`),u?.value_preview&&e.push(`值: ${u.value_preview}`),e.length?e.join(" · "):"-"}function me(u){const e=String(u?.request_method||"").trim(),R=String(u?.request_path||"").trim();return`${e} ${R}`.trim()||"-"}const Te=B(()=>{const u=new Set(ae),e=f.value?.recent_threat_events||[];for(const R of e){const D=String(R?.threat_type||"").trim();D&&u.add(D)}for(const R of d.value||[]){const D=String(R?.threat_type||"").trim();D&&u.add(D)}return Array.from(u).sort((R,D)=>R.localeCompare(D)).map(R=>({label:R,value:R}))}),Ve=B(()=>{const u=f.value||{};return[{key:"threat_events_24h",label:"最近24小时威胁事件",value:X(u.threat_events_24h),tone:"red",hint:"用于衡量当前攻击面活跃度"},{key:"banned_ip_count",label:"当前封禁 IP 数",value:X(u.banned_ip_count),tone:"orange",hint:"自动与人工封禁总量"},{key:"banned_user_count",label:"当前封禁用户数",value:X(u.banned_user_count),tone:"purple",hint:"高风险账户拦截情况"}]}),je=B(()=>Math.max(1,Math.ceil((k.value||0)/Ze)));async function te(){r.value=!0;try{f.value=await bl()}catch{f.value=null}finally{r.value=!1}}async function le(){i.value=!0;try{const u={page:h.value,per_page:Ze};v.value&&(u.event_type=v.value),_.value&&(u.severity=_.value);const e=await ml(u);d.value=e?.items||[],k.value=e?.total||0}catch{d.value=[],k.value=0}finally{i.value=!1}}async function ue(){if(!C.value){C.value=!0;try{const[u,e]=await Promise.allSettled([_l(),yl()]);g.value=u.status==="fulfilled"?u.value?.items||[]:[],c.value=e.status==="fulfilled"?e.value?.items||[]:[]}finally{C.value=!1}}}async function Re(){await Promise.allSettled([te(),le(),ue()])}function I(){h.value=1,le()}function x(){v.value="",_.value="",h.value=1,le()}function E(){S.value={kind:"ip",ip:"",user_id:"",reason:"",duration_hours:24,permanent:!1}}function $(u="ip",e={}){E(),S.value.kind=u==="user"?"user":"ip",S.value.kind==="ip"?S.value.ip=String(e.ip||"").trim():S.value.user_id=String(e.user_id||"").trim(),e.reason&&(S.value.reason=String(e.reason||"").trim()),w.value=!0}async function z(){const u=S.value.kind,e=String(S.value.reason||"").trim(),R=!!S.value.permanent,D=Number(S.value.duration_hours||24);if(!e){Q.error("原因不能为空");return}if(u==="ip"){const ee=String(S.value.ip||"").trim();if(!ee){Q.error("IP不能为空");return}m.value=!0;try{await hl({ip:ee,reason:e,duration_hours:D,permanent:R}),Q.success("IP已封禁"),w.value=!1,await Promise.allSettled([te(),ue()])}catch{}finally{m.value=!1}return}const xe=String(S.value.user_id||"").trim(),F=Number.parseInt(xe,10);if(!Number.isFinite(F)){Q.error("用户ID无效");return}m.value=!0;try{await wl({user_id:F,reason:e,duration_hours:D,permanent:R}),Q.success("用户已封禁"),w.value=!1,await Promise.allSettled([te(),ue()])}catch{}finally{m.value=!1}}async function de(u){const e=String(u||"").trim();if(e){try{await ze.confirm(`确定解除对 IP ${e} 的封禁吗?`,"解除封禁",{confirmButtonText:"解除",cancelButtonText:"取消",type:"warning"})}catch{return}try{await gl(e),Q.success("已解除IP封禁"),await Promise.allSettled([te(),ue()])}catch{}}}async function Z(u){const e=Number.parseInt(String(u||"").trim(),10);if(Number.isFinite(e)){try{await ze.confirm(`确定解除对 用户ID ${e} 的封禁吗?`,"解除封禁",{confirmButtonText:"解除",cancelButtonText:"取消",type:"warning"})}catch{return}try{await kl(e),Q.success("已解除用户封禁"),await Promise.allSettled([te(),ue()])}catch{}}}function j(u){const e=String(u||"").trim();e&&(s.value="risk",O.value="ip",A.value=e,ne())}function Ne(u){const e=String(u||"").trim();e&&(s.value="risk",O.value="user",G.value=e,se())}async function ne(){const u=String(A.value||"").trim();if(!u){Q.error("请输入IP");return}b.value=!0;try{N.value=await Cl(u),L.value="ip"}catch{N.value=null,L.value=""}finally{b.value=!1}}async function se(){const u=String(G.value||"").trim(),e=Number.parseInt(u,10);if(!Number.isFinite(e)){Q.error("请输入有效的用户ID");return}b.value=!0;try{N.value=await El(e),L.value="user"}catch{N.value=null,L.value=""}finally{b.value=!1}}function we(){!N.value||!L.value||(L.value==="ip"?$("ip",{ip:N.value?.ip,reason:"风险查询手动封禁"}):$("user",{user_id:N.value?.user_id,reason:"风险查询手动封禁"}))}async function He(){!N.value||!L.value||(L.value==="ip"?(await de(N.value?.ip),await ne()):(await Z(N.value?.user_id),await se()))}async function We(){if(L.value!=="ip")return;const u=String(N.value?.ip||"").trim();if(u){try{await ze.confirm(`确定清除 IP ${u} 的风险分吗? 清除风险分不会删除威胁历史,也不会解除封禁。`,"清除风险分",{confirmButtonText:"清除",cancelButtonText:"取消",type:"warning"})}catch{return}if(!b.value){b.value=!0;try{await Sl(u),Q.success("IP风险分已清零")}catch{}finally{b.value=!1}await ne()}}}const ke=y(!1);async function J(){try{await ze.confirm(`确定清理过期封禁记录,并衰减风险分吗? 该操作不会影响仍在有效期内的封禁。`,"清理过期记录",{confirmButtonText:"清理",cancelButtonText:"取消",type:"warning"})}catch{return}ke.value=!0;try{await Il(),Q.success("清理完成"),await Re()}catch{}finally{ke.value=!1}}return Me(async()=>{await Re()}),(u,e)=>{const R=tt,D=ht,xe=yt,F=mt,ee=_t,$e=gt,Be=lt,Fe=bt,Fa=ft,ce=pl,qe=vl,Ce=nt,oa=st,ia=qt,Ua=Wt,_e=ut,za=dt,Oa=ct,Aa=rt,La=it,Ue=ot;return V(),W("div",Pl,[T("div",Tl,[e[20]||(e[20]=T("h2",null,"安全防护",-1)),T("div",Vl,[a(R,{type:"warning",plain:"",loading:ke.value,onClick:J},{default:n(()=>[...e[18]||(e[18]=[P("清理过期记录",-1)])]),_:1},8,["loading"]),a(R,{type:"primary",onClick:e[0]||(e[0]=l=>$())},{default:n(()=>[...e[19]||(e[19]=[P("手动封禁",-1)])]),_:1})])]),a(wt,{items:Ve.value,loading:r.value,"min-width":220},null,8,["items","loading"]),a(oa,{shadow:"never","body-style":{padding:"16px"},class:"card"},{default:n(()=>[a(qe,{modelValue:s.value,"onUpdate:modelValue":e[9]||(e[9]=l=>s.value=l)},{default:n(()=>[a(ce,{label:"威胁事件",name:"threats"},{default:n(()=>[T("div",Rl,[a(xe,{modelValue:v.value,"onUpdate:modelValue":e[1]||(e[1]=l=>v.value=l),placeholder:"类型",style:{width:"220px"},filterable:"",clearable:"","allow-create":"","default-first-option":""},{default:n(()=>[a(D,{label:"全部",value:""}),(V(!0),W(ga,null,wa(Te.value,l=>(V(),M(D,{key:l.value,label:l.label,value:l.value},null,8,["label","value"]))),128))]),_:1},8,["modelValue"]),a(xe,{modelValue:_.value,"onUpdate:modelValue":e[2]||(e[2]=l=>_.value=l),placeholder:"严重程度",style:{width:"200px"},clearable:""},{default:n(()=>[a(D,{label:"全部",value:""}),a(D,{label:"高风险(>=80)",value:"high"}),a(D,{label:"中风险(50-79)",value:"medium"}),a(D,{label:"低风险(<50)",value:"low"})]),_:1},8,["modelValue"]),a(R,{type:"primary",onClick:I},{default:n(()=>[...e[21]||(e[21]=[P("筛选",-1)])]),_:1}),a(R,{onClick:x},{default:n(()=>[...e[22]||(e[22]=[P("重置",-1)])]),_:1})]),T("div",Nl,[fe((V(),M(Fe,{data:d.value,style:{width:"100%"}},{default:n(()=>[a(F,{prop:"created_at",label:"时间",width:"180"}),a(F,{label:"类型",width:"170"},{default:n(({row:l})=>[a(ee,{effect:"light",type:"info"},{default:n(()=>[P(U(l.threat_type||"unknown"),1)]),_:2},1024)]),_:1}),a(F,{label:"严重程度",width:"120"},{default:n(({row:l})=>[a(ee,{type:K(l.score).type,effect:"light"},{default:n(()=>[P(U(K(l.score).label)+" ("+U(l.score??0)+") ",1)]),_:2},1032,["type"])]),_:1}),a(F,{label:"IP",width:"150"},{default:n(({row:l})=>[l.ip?(V(),M($e,{key:0,type:"primary",underline:!1,onClick:Se=>j(l.ip)},{default:n(()=>[P(U(l.ip),1)]),_:2},1032,["onClick"])):(V(),W("span",xl,"-"))]),_:1}),a(F,{label:"用户",width:"120"},{default:n(({row:l})=>[l.user_id!==null&&l.user_id!==void 0?(V(),M($e,{key:0,type:"primary",underline:!1,onClick:Se=>Ne(l.user_id)},{default:n(()=>[P(U(l.user_id),1)]),_:2},1032,["onClick"])):(V(),W("span",$l,"-"))]),_:1}),a(F,{label:"操作路径","min-width":"220"},{default:n(({row:l})=>[a(Be,{content:me(l),placement:"top","show-after":300},{default:n(()=>[T("span",Bl,U(me(l)),1)]),_:2},1032,["content"])]),_:1}),a(F,{label:"Payload预览","min-width":"240"},{default:n(({row:l})=>[a(Be,{content:Pe(l),placement:"top","show-after":300},{default:n(()=>[T("span",Fl,U(l.value_preview||"-"),1)]),_:2},1032,["content"])]),_:1})]),_:1},8,["data"])),[[Ue,i.value]])]),T("div",Ul,[a(Fa,{"current-page":h.value,"onUpdate:currentPage":e[3]||(e[3]=l=>h.value=l),"page-size":Ze,total:k.value,layout:"prev, pager, next, jumper, ->, total",onCurrentChange:le},null,8,["current-page","total"]),T("div",zl,"第 "+U(h.value)+" / "+U(je.value)+" 页",1)])]),_:1}),a(ce,{label:"封禁管理",name:"bans"},{default:n(()=>[T("div",Ol,[a(R,{type:"primary",onClick:e[4]||(e[4]=l=>$())},{default:n(()=>[...e[23]||(e[23]=[P("手动封禁",-1)])]),_:1})]),a(qe,{modelValue:p.value,"onUpdate:modelValue":e[5]||(e[5]=l=>p.value=l),class:"inner-tabs"},{default:n(()=>[a(ce,{label:"IP黑名单",name:"ips"},{default:n(()=>[T("div",Al,[fe((V(),M(Fe,{data:g.value,style:{width:"100%"}},{default:n(()=>[a(F,{label:"IP",width:"180"},{default:n(({row:l})=>[a($e,{type:"primary",underline:!1,onClick:Se=>j(l.ip)},{default:n(()=>[P(U(l.ip||"-"),1)]),_:2},1032,["onClick"])]),_:1}),a(F,{prop:"reason",label:"原因","min-width":"260"}),a(F,{label:"过期时间",width:"190"},{default:n(({row:l})=>[P(U(be(l.expires_at)),1)]),_:1}),a(F,{label:"操作",width:"120",fixed:"right"},{default:n(({row:l})=>[a(R,{size:"small",type:"danger",plain:"",onClick:Se=>de(l.ip)},{default:n(()=>[...e[24]||(e[24]=[P("解除",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"])),[[Ue,C.value]])])]),_:1}),a(ce,{label:"用户黑名单",name:"users"},{default:n(()=>[T("div",Ll,[fe((V(),M(Fe,{data:c.value,style:{width:"100%"}},{default:n(()=>[a(F,{label:"用户ID",width:"180"},{default:n(({row:l})=>[a($e,{type:"primary",underline:!1,onClick:Se=>Ne(l.user_id)},{default:n(()=>[P(U(l.user_id??"-"),1)]),_:2},1032,["onClick"])]),_:1}),a(F,{prop:"reason",label:"原因","min-width":"260"}),a(F,{label:"过期时间",width:"190"},{default:n(({row:l})=>[P(U(be(l.expires_at)),1)]),_:1}),a(F,{label:"操作",width:"120",fixed:"right"},{default:n(({row:l})=>[a(R,{size:"small",type:"danger",plain:"",onClick:Se=>Z(l.user_id)},{default:n(()=>[...e[25]||(e[25]=[P("解除",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"])),[[Ue,C.value]])])]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(ce,{label:"风险查询",name:"risk"},{default:n(()=>[a(qe,{modelValue:O.value,"onUpdate:modelValue":e[8]||(e[8]=l=>O.value=l),class:"inner-tabs"},{default:n(()=>[a(ce,{label:"IP查询",name:"ip"},{default:n(()=>[T("div",Dl,[a(Ce,{modelValue:A.value,"onUpdate:modelValue":e[6]||(e[6]=l=>A.value=l),placeholder:"输入IP,如 1.2.3.4",style:{width:"260px"},clearable:""},null,8,["modelValue"]),a(R,{type:"primary",loading:b.value,onClick:ne},{default:n(()=>[...e[26]||(e[26]=[P("查询",-1)])]),_:1},8,["loading"])])]),_:1}),a(ce,{label:"用户查询",name:"user"},{default:n(()=>[T("div",Ml,[a(Ce,{modelValue:G.value,"onUpdate:modelValue":e[7]||(e[7]=l=>G.value=l),placeholder:"输入用户ID,如 123",style:{width:"260px"},clearable:""},null,8,["modelValue"]),a(R,{type:"primary",loading:b.value,onClick:se},{default:n(()=>[...e[27]||(e[27]=[P("查询",-1)])]),_:1},8,["loading"])])]),_:1})]),_:1},8,["modelValue"]),N.value?(V(),M(oa,{key:0,shadow:"never","body-style":{padding:"16px"},class:"sub-card"},{default:n(()=>[T("div",Gl,[T("div",Kl,[L.value==="ip"?(V(),W("strong",jl,"IP: "+U(N.value.ip),1)):(V(),W("strong",Hl,"用户ID: "+U(N.value.user_id),1)),e[30]||(e[30]=T("span",{class:"app-muted"},"风险分",-1)),a(ee,{type:K(N.value.risk_score).type,effect:"light"},{default:n(()=>[P(U(N.value.risk_score??0),1)]),_:1},8,["type"]),N.value.is_banned?(V(),M(ee,{key:2,type:"danger",effect:"light"},{default:n(()=>[...e[28]||(e[28]=[P("已封禁",-1)])]),_:1})):(V(),M(ee,{key:3,type:"success",effect:"light"},{default:n(()=>[...e[29]||(e[29]=[P("未封禁",-1)])]),_:1}))]),T("div",Wl,[N.value.is_banned?(V(),M(R,{key:1,type:"danger",plain:"",onClick:He},{default:n(()=>[...e[32]||(e[32]=[P("解除封禁",-1)])]),_:1})):(V(),M(R,{key:0,type:"primary",plain:"",onClick:we},{default:n(()=>[...e[31]||(e[31]=[P("封禁",-1)])]),_:1})),L.value==="ip"?(V(),M(R,{key:2,type:"warning",plain:"",loading:b.value,onClick:We},{default:n(()=>[...e[33]||(e[33]=[P(" 清除风险分 ",-1)])]),_:1},8,["loading"])):Le("",!0)])]),T("div",ql,[fe((V(),M(Fe,{data:N.value.threat_history||[],style:{width:"100%"}},{default:n(()=>[a(F,{prop:"created_at",label:"时间",width:"180"}),a(F,{label:"类型",width:"170"},{default:n(({row:l})=>[a(ee,{effect:"light",type:"info"},{default:n(()=>[P(U(l.threat_type||"unknown"),1)]),_:2},1024)]),_:1}),a(F,{label:"严重程度",width:"120"},{default:n(({row:l})=>[a(ee,{type:K(l.score).type,effect:"light"},{default:n(()=>[P(U(K(l.score).label)+" ("+U(l.score??0)+") ",1)]),_:2},1032,["type"])]),_:1}),a(F,{label:"操作路径","min-width":"220"},{default:n(({row:l})=>[a(Be,{content:me(l),placement:"top","show-after":300},{default:n(()=>[T("span",Xl,U(me(l)),1)]),_:2},1032,["content"])]),_:1}),a(F,{label:"Payload预览","min-width":"240"},{default:n(({row:l})=>[a(Be,{content:Pe(l),placement:"top","show-after":300},{default:n(()=>[T("span",Zl,U(l.value_preview||"-"),1)]),_:2},1032,["content"])]),_:1})]),_:1},8,["data"])),[[Ue,b.value]])])]),_:1})):Le("",!0)]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(La,{modelValue:w.value,"onUpdate:modelValue":e[17]||(e[17]=l=>w.value=l),title:"手动封禁",width:"min(520px, 92vw)",onClosed:E},{footer:n(()=>[T("div",Jl,[e[38]||(e[38]=T("div",{class:"spacer"},null,-1)),a(R,{onClick:e[16]||(e[16]=l=>w.value=!1)},{default:n(()=>[...e[36]||(e[36]=[P("取消",-1)])]),_:1}),a(R,{type:"primary",loading:m.value,onClick:z},{default:n(()=>[...e[37]||(e[37]=[P("确认封禁",-1)])]),_:1},8,["loading"])])]),default:n(()=>[a(Aa,{"label-width":"120px"},{default:n(()=>[a(_e,{label:"类型"},{default:n(()=>[a(Ua,{modelValue:S.value.kind,"onUpdate:modelValue":e[10]||(e[10]=l=>S.value.kind=l)},{default:n(()=>[a(ia,{label:"ip"},{default:n(()=>[...e[34]||(e[34]=[P("IP",-1)])]),_:1}),a(ia,{label:"user"},{default:n(()=>[...e[35]||(e[35]=[P("用户",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),S.value.kind==="ip"?(V(),M(_e,{key:0,label:"IP"},{default:n(()=>[a(Ce,{modelValue:S.value.ip,"onUpdate:modelValue":e[11]||(e[11]=l=>S.value.ip=l),placeholder:"例如 1.2.3.4"},null,8,["modelValue"])]),_:1})):(V(),M(_e,{key:1,label:"用户ID"},{default:n(()=>[a(Ce,{modelValue:S.value.user_id,"onUpdate:modelValue":e[12]||(e[12]=l=>S.value.user_id=l),placeholder:"例如 123"},null,8,["modelValue"])]),_:1})),a(_e,{label:"原因"},{default:n(()=>[a(Ce,{modelValue:S.value.reason,"onUpdate:modelValue":e[13]||(e[13]=l=>S.value.reason=l),type:"textarea",rows:3,placeholder:"请输入封禁原因"},null,8,["modelValue"])]),_:1}),a(_e,{label:"永久封禁"},{default:n(()=>[a(za,{modelValue:S.value.permanent,"onUpdate:modelValue":e[14]||(e[14]=l=>S.value.permanent=l)},null,8,["modelValue"])]),_:1}),S.value.permanent?Le("",!0):(V(),M(_e,{key:2,label:"持续(小时)"},{default:n(()=>[a(Oa,{modelValue:S.value.duration_hours,"onUpdate:modelValue":e[15]||(e[15]=l=>S.value.duration_hours=l),min:1,max:8760},null,8,["modelValue"])]),_:1}))]),_:1})]),_:1},8,["modelValue"])])}}},mn=at(Ql,[["__scopeId","data-v-94e0bde6"]]);export{mn as default};