feat(audit): F1+F2 告警静默规则标记完成 + 审计日志CSV导出实现

F1 告警静默规则 [done]:
- 后端 alert_silence.go: CRUD + Toggle (onetime/daily/weekly 三模式)
- 告警引擎 isSilenced 集成 (alert_engine.go)
- 前端 SilenceRuleTab + SilenceDialog
- 路由 /alerts/silences 已注册

F2 审计日志导出 [done]:
- 重写 ExportAuditLogs: 真正的 CSV 导出 (encoding/csv + UTF-8 BOM)
- 支持 module/action/username/startTime/endTime 筛选
- 导出限制 10000 条防溢出,自动记录审计日志
- JSON 格式向后兼容 (format=json)
- 前端 exportLogs 传递查询参数

同时包含累积的前期工作:
- 目录重构 internal/ -> controller/model/router (v0.55-v0.57)
- 后端分层架构 dto/repository/service/utils
- 审计模块全功能 (终端审计/操作审计/登录日志)
- asciicast v2 录制格式
- SFTP 文件浏览器
- StatStrip 紧凑统计条
- 在线会话自动刷新
- LiveMonitor WebSocket 诊断修复

验证: go build ✅ | npm run build ✅ | Docker 部署 ✅ | 10 回归端点 ✅ | CSV 导出 ✅ | 静默 CRUD ✅
This commit is contained in:
attacker committed 2026-06-25 20:16:30 +08:00
1 parent e57718998a
commit 77c234b060
314 files changed
+10050 -4065

No files matched your search

+1
View File
@@ -0,0 +1 @@
import{g as ot,r as n,j as a,ar as nt,as as Pe,aj as rt,af as Te,at as st,ac as at,ak as Ie,au as ct,ag as L,av as lt,ae as j,ah as E,aw as $,ax as it,ay as _e,az as dt,aA as ut,aB as pt,aC as ft,aD as mt,aE as ht,aF as gt,aG as vt,aH as Ee,aI as xt,X as te,a4 as Ne,a9 as St}from"./index-DfyorCky.js";import{u as wt}from"./index-CWVNW_qu.js";const yt=[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]],Ct=ot("chevron-up",yt);function It(t){const o=bt(t),e=n.forwardRef((s,r)=>{const{children:d,...c}=s,l=n.Children.toArray(d),i=l.find(Et);if(i){const p=i.props.children,g=l.map(x=>x===i?n.Children.count(p)>1?n.Children.only(null):n.isValidElement(p)?p.props.children:null:x);return a.jsx(o,{...c,ref:r,children:n.isValidElement(p)?n.cloneElement(p,void 0,g):null})}return a.jsx(o,{...c,ref:r,children:d})});return e.displayName=`${t}.Slot`,e}function bt(t){const o=n.forwardRef((e,s)=>{const{children:r,...d}=e;if(n.isValidElement(r)){const c=_t(r),l=Pt(d,r.props);return r.type!==n.Fragment&&(l.ref=s?nt(s,c):c),n.cloneElement(r,l)}return n.Children.count(r)>1?n.Children.only(null):null});return o.displayName=`${t}.SlotClone`,o}var Tt=Symbol("radix.slottable");function Et(t){return n.isValidElement(t)&&typeof t.type=="function"&&"__radixId"in t.type&&t.type.__radixId===Tt}function Pt(t,o){const e={...o};for(const s in o){const r=t[s],d=o[s];/^on[A-Z]/.test(s)?r&&d?e[s]=(...l)=>{const i=d(...l);return r(...l),i}:r&&(e[s]=r):s==="style"?e[s]={...r,...d}:s==="className"&&(e[s]=[r,d].filter(Boolean).join(" "))}return{...t,...e}}function _t(t){let o=Object.getOwnPropertyDescriptor(t.props,"ref")?.get,e=o&&"isReactWarning"in o&&o.isReactWarning;return e?t.ref:(o=Object.getOwnPropertyDescriptor(t,"ref")?.get,e=o&&"isReactWarning"in o&&o.isReactWarning,e?t.props.ref:t.props.ref||t.ref)}var Nt=[" ","Enter","ArrowUp","ArrowDown"],Rt=[" ","Enter"],J="Select",[ie,de,jt]=ct(J),[oe]=at(J,[jt,Pe]),ue=Pe(),[At,G]=oe(J),[Mt,Ot]=oe(J),Re=t=>{const{__scopeSelect:o,children:e,open:s,defaultOpen:r,onOpenChange:d,value:c,defaultValue:l,onValueChange:i,dir:p,name:g,autoComplete:x,disabled:P,required:b,form:C}=t,u=ue(o),[h,S]=n.useState(null),[m,v]=n.useState(null),[F,A]=n.useState(!1),ne=rt(p),[_,O]=Te({prop:s,defaultProp:r??!1,onChange:d,caller:J}),[U,q]=Te({prop:c,defaultProp:l,onChange:i,caller:J}),k=n.useRef(null),V=h?C||!!h.closest("form"):!0,[z,B]=n.useState(new Set),H=Array.from(z).map(N=>N.props.value).join(";");return a.jsx(st,{...u,children:a.jsxs(At,{required:b,scope:o,trigger:h,onTriggerChange:S,valueNode:m,onValueNodeChange:v,valueNodeHasChildren:F,onValueNodeHasChildrenChange:A,contentId:Ie(),value:U,onValueChange:q,open:_,onOpenChange:O,dir:ne,triggerPointerDownPosRef:k,disabled:P,children:[a.jsx(ie.Provider,{scope:o,children:a.jsx(Mt,{scope:t.__scopeSelect,onNativeOptionAdd:n.useCallback(N=>{B(D=>new Set(D).add(N))},[]),onNativeOptionRemove:n.useCallback(N=>{B(D=>{const W=new Set(D);return W.delete(N),W})},[]),children:e})}),V?a.jsxs(Je,{"aria-hidden":!0,required:b,tabIndex:-1,name:g,autoComplete:x,value:U,onChange:N=>q(N.target.value),disabled:P,form:C,children:[U===void 0?a.jsx("option",{value:""}):null,Array.from(z)]},H):null]})})};Re.displayName=J;var je="SelectTrigger",Ae=n.forwardRef((t,o)=>{const{__scopeSelect:e,disabled:s=!1,...r}=t,d=ue(e),c=G(je,e),l=c.disabled||s,i=L(o,c.onTriggerChange),p=de(e),g=n.useRef("touch"),[x,P,b]=et(u=>{const h=p().filter(v=>!v.disabled),S=h.find(v=>v.value===c.value),m=tt(h,u,S);m!==void 0&&c.onValueChange(m.value)}),C=u=>{l||(c.onOpenChange(!0),b()),u&&(c.triggerPointerDownPosRef.current={x:Math.round(u.pageX),y:Math.round(u.pageY)})};return a.jsx(lt,{asChild:!0,...d,children:a.jsx(j.button,{type:"button",role:"combobox","aria-controls":c.contentId,"aria-expanded":c.open,"aria-required":c.required,"aria-autocomplete":"none",dir:c.dir,"data-state":c.open?"open":"closed",disabled:l,"data-disabled":l?"":void 0,"data-placeholder":Qe(c.value)?"":void 0,...r,ref:i,onClick:E(r.onClick,u=>{u.currentTarget.focus(),g.current!=="mouse"&&C(u)}),onPointerDown:E(r.onPointerDown,u=>{g.current=u.pointerType;const h=u.target;h.hasPointerCapture(u.pointerId)&&h.releasePointerCapture(u.pointerId),u.button===0&&u.ctrlKey===!1&&u.pointerType==="mouse"&&(C(u),u.preventDefault())}),onKeyDown:E(r.onKeyDown,u=>{const h=x.current!=="";!(u.ctrlKey||u.altKey||u.metaKey)&&u.key.length===1&&P(u.key),!(h&&u.key===" ")&&Nt.includes(u.key)&&(C(),u.preventDefault())})})})});Ae.displayName=je;var Me="SelectValue",Oe=n.forwardRef((t,o)=>{const{__scopeSelect:e,className:s,style:r,children:d,placeholder:c="",...l}=t,i=G(Me,e),{onValueNodeHasChildrenChange:p}=i,g=d!==void 0,x=L(o,i.onValueNodeChange);return $(()=>{p(g)},[p,g]),a.jsx(j.span,{...l,ref:x,style:{pointerEvents:"none"},children:Qe(i.value)?a.jsx(a.Fragment,{children:c}):d})});Oe.displayName=Me;var Dt="SelectIcon",De=n.forwardRef((t,o)=>{const{__scopeSelect:e,children:s,...r}=t;return a.jsx(j.span,{"aria-hidden":!0,...r,ref:o,children:s||"▼"})});De.displayName=Dt;var LLine truncated