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

@@ -0,0 +1,2 @@
import{r as o,u as q,j as s,D as X,b as G,c as Y,d as Z,a8 as le,e as ss,I as S,f as ms,B as i,P as qs,a3 as Js,N as Ws,L as Ns,S as Ne,U as re,t as Us,a as Xs,a4 as ve,aa as de,y as Vs,V as Te,E as pe,l as z,z as Le}from"./index-DfyorCky.js";import{T as De,a as fe,b as Hs,c as Ks}from"./tabs-CIh_yD4s.js";import{B as os}from"./badge-xNW8x0G1.js";import{C as xs,a as hs,b as Ss,c as js,d as us}from"./card-C55cvSHg.js";import{T as Ps,a as zs,b as J,c as U,d as Es,e as T}from"./table-5sHV4Akp.js";import{S as ws,a as Cs,b as Ms,c as Is,d as B}from"./select-D5qUzdAs.js";import{S as vs}from"./square-pen-BxUFAe0F.js";import{U as Qs}from"./upload-Ba6rlaGS.js";import{D as ie}from"./download-DoZfYs2h.js";import{C as Gs}from"./circle-x-DK79Dhg2.js";import{R as Ys}from"./refresh-cw-DUB_tAG-.js";import{P as Zs}from"./plus-CUG-9kpu.js";import{M as Ue,P as we}from"./phone-DgvWDdJl.js";import{T as se}from"./trash-2-Dx32pOzT.js";import{t as Q}from"./index-a3ybMjbR.js";import{T as Ce}from"./textarea-NXY8u32k.js";import{L as fs}from"./label-BK0h2apY.js";import{C as Me}from"./checkbox-CH0bpj6b.js";import{S as bs}from"./switch-CGiGgOnh.js";import{U as Ie}from"./user-plus-BwUWtcQl.js";import{H as ke}from"./history-D_9jPUQg.js";import"./index-CWVNW_qu.js";function Re({open:e,onOpenChange:r,editingUser:t,form:n,setForm:d,saving:x,onSubmit:D}){const[N,b]=o.useState([]);return o.useEffect(()=>{if(!e)return;let a=!1;return(async()=>{try{const u=await q.getRoles();if(a)return;const I=u?.list??[];b(I.map(L=>({id:String(L.id??""),name:L.name??L.code??""})))}catch{a||b([])}})(),()=>{a=!0}},[e]),s.jsx(X,{"code-path":"src/components/system/UserFormDialog.tsx:78:5",open:e,onOpenChange:r,children:s.jsxs(G,{"code-path":"src/components/system/UserFormDialog.tsx:79:7",className:"bg-slate-900 border-slate-800",children:[s.jsxs(Y,{"code-path":"src/components/system/UserFormDialog.tsx:80:9",children:[s.jsxs(Z,{"code-path":"src/components/system/UserFormDialog.tsx:81:11",className:"text-slate-100 flex items-center gap-2",children:[s.jsx(le,{"code-path":"src/components/system/UserFormDialog.tsx:82:13",className:"h-5 w-5 text-blue-400"}),t?"编辑用户":"新建用户"]}),s.jsx(ss,{"code-path":"src/components/system/UserFormDialog.tsx:85:11",className:"text-slate-500",children:t?"修改用户信息":"创建新的系统用户"})]}),s.jsxs("div",{"code-path":"src/components/system/UserFormDialog.tsx:90:9",className:"space-y-4",children:[s.jsxs("div",{"code-path":"src/components/system/UserFormDialog.tsx:91:11",className:"grid grid-cols-2 gap-4",children:[s.jsxs("div",{"code-path":"src/components/system/UserFormDialog.tsx:92:13",className:"space-y-2",children:[s.jsx("label",{"code-path":"src/components/system/UserFormDialog.tsx:93:15",className:"text-xs text-slate-500",children:"用户名"}),s.jsx(S,{"code-path":"src/components/system/UserFormDialog.tsx:94:15",value:n.username,onChange:a=>d({...n,username:a.target.value}),disabled:!!t,className:"bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-500",placeholder:"登录用户名"})]}),s.jsxs("div",{"code-path":"src/components/system/UserFormDialog.tsx:102:13",className:"space-y-2",children:[s.jsx("label",{"code-path":"src/components/system/UserFormDialog.tsx:103:15",className:"text-xs text-slate-500",children:"昵称"}),s.jsx(S,{"code-path":"src/components/system/UserFormDialog.tsx:104:15",value:n.nickname,onChange:a=>d({...n,nickname:a.target.value}),className:"bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-500",placeholder:"显示昵称"})]}),s.jsxs("div",{"code-path":"src/components/system/UserFormDialog.tsx:111:13",className:"space-y-2",children:[s.jsx("label",{"code-path":"src/components/system/UserFormDialog.tsx:112:15",className:"text-xs text-slate-500",children:"邮箱"}),s.jsx(S,{"code-path":"src/components/system/UserFormDialog.tsx:113:15",value:n.email,onChange:a=>d({...n,email:a.target.value}),className:"bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-500",placeholder:"user@example.com"})]}),s.jsxs("div",{"code-path":"src/components/system/UserFormDialog.tsx:120:13",className:"space-y-2",children:[s.jsx("label",{"code-path":"src/components/system/UserFormDialog.tsx:121:15",className:"text-xs text-slate-500",children:"手机号"}),s.jsx(S,{"code-path":"src/components/system/UserFormDialog.tsx:122:15",value:n.phone,onChange:a=>d({...n,phone:a.target.value}),className:"bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-500",placeholder:"可选"})]}),s.jsxs("div",{"code-path":"src/components/system/UserFormDialog.tsx:129:13",className:"space-y-2",children:[s.jsx("label",{"code-path":"src/components/system/UserFormDialog.tsx:130:15",className:"text-xs text-slate-500",children:"角色"}),s.jsxs(ws,{"code-path":"src/components/system/UserFormDialog.tsx:131:15",value:n.role,onValueChange:a=>d({...n,role:a}),children:[s.jsx(Cs,{"code-path":"src/components/system/UserFormDialog.tsx:132:17",className:"bg-slate-800/50Line truncated
`).filter(h=>h.trim()&&!h.startsWith(""));if(c.length<2)return;const K=c[0].split(",").map(h=>h.trim().toLowerCase()),is=K.findIndex(h=>h.includes("用户名")||h.includes("username")),Rs=K.findIndex(h=>h.includes("昵称")||h.includes("name")||h.includes("显示名")),Fs=K.findIndex(h=>h.includes("邮箱")||h.includes("email")||h.includes("mail")),Ls=K.findIndex(h=>h.includes("手机")||h.includes("phone")),_s=K.findIndex(h=>h.includes("角色")||h.includes("role")),ys=K.findIndex(h=>h.includes("密码")||h.includes("password")),gs=[];for(let h=1;h<c.length;h++){const ns=c[h].split(",").map(Os=>Os.trim());gs.push({username:is>=0?ns[is]:"",nickname:Rs>=0?ns[Rs]:"",email:Fs>=0?ns[Fs]:"",phone:Ls>=0?ns[Ls]:"",role:_s>=0?ns[_s]:"",password:ys>=0?ns[ys]:""})}$(gs),ts(null)},cs.readAsText(P,"UTF-8")},ps=async()=>{j.setImporting(!0);try{const l=await q.batchImport({users:g,skip_existing:!0});ts(l),await W()}catch(l){ts({code:500,message:l?.message||"导入失败"})}finally{j.setImporting(!1)}};return s.jsxs("div",{"code-path":"src/components/system/SystemManager.tsx:232:5",className:"space-y-6",children:[s.jsx("div",{"code-path":"src/components/system/SystemManager.tsx:234:7",className:"flex items-center justify-between",children:s.jsxs("div",{"code-path":"src/components/system/SystemManager.tsx:235:9",children:[s.jsx("h1",{"code-path":"src/components/system/SystemManager.tsx:236:11",className:"text-2xl font-bold text-slate-100",children:"系统管理"}),s.jsx("p",{"code-path":"src/components/system/SystemManager.tsx:237:11",className:"text-sm text-slate-500 mt-1",children:"用户、权限与系统配置"})]})}),s.jsxs(De,{"code-path":"src/components/system/SystemManager.tsx:242:7",value:n,onValueChange:d,className:"w-full",children:[s.jsxs(fe,{"code-path":"src/components/system/SystemManager.tsx:243:9",className:"bg-slate-800 border border-slate-700",children:[s.jsxs(Hs,{"code-path":"src/components/system/SystemManager.tsx:244:11",value:"users",className:"data-[state=active]:bg-slate-700",children:[s.jsx(de,{"code-path":"src/components/system/SystemManager.tsx:245:13",className:"h-4 w-4 mr-2"}),"用户管理"]}),s.jsxs(Hs,{"code-path":"src/components/system/SystemManager.tsx:248:11",value:"roles",className:"data-[state=active]:bg-slate-700",children:[s.jsx(Us,{"code-path":"src/components/system/SystemManager.tsx:249:13",className:"h-4 w-4 mr-2"}),"角色权限"]}),s.jsxs(Hs,{"code-path":"src/components/system/SystemManager.tsx:252:11",value:"settings",className:"data-[state=active]:bg-slate-700",children:[s.jsx(pe,{"code-path":"src/components/system/SystemManager.tsx:253:13",className:"h-4 w-4 mr-2"}),"系统设置"]})]}),s.jsx(Ks,{"code-path":"src/components/system/SystemManager.tsx:258:9",value:"users",className:"mt-4 space-y-4",children:s.jsx(Ae,{"code-path":"src/components/system/SystemManager.tsx:259:11",searchQuery:x,setSearchQuery:D,filteredUsers:ls,loading:a,selectedUser:I,setSelectedUser:L,getUserStatusBadge:as,dialogOpen:y,setDialogOpen:k,editingUser:f,form:C,setForm:_,saving:F,handleSubmit:V,openCreate:rs,openEdit:ds,handleDelete:v,importDialogOpen:p,setImportDialogOpen:O,importPreview:g,setImportPreview:$,importing:j.importing,importResult:es,setImportResult:ts,handleCsvUpload:H,handleBatchImport:ps,ldapUsers:j.ldapUsers,ldapSelected:j.ldapSelected,setLdapSelected:j.setLdapSelected,ldapLoading:j.ldapLoading,ldapImportOUs:j.ldapImportOUs,ldapImportOUDN:j.ldapImportOUDN,setLdapImportOUDN:j.setLdapImportOUDN,loadLdapUsers:j.loadLdapUsers,handleLdapImport:j.handleLdapImport,setLdapUsers:j.setLdapUsers})}),s.jsx(Ks,{"code-path":"src/components/system/SystemManager.tsx:299:9",value:"roles",className:"mt-4 space-y-4",children:s.jsx(Ee,{"code-path":"src/components/system/SystemManager.tsx:300:11",selectedRole:w,setSelectedRole:R})}),s.jsx(Ks,{"code-path":"src/components/system/SystemManager.tsx:306:9",value:"settings",className:"mt-4",children:s.jsx(Ve,{"code-path":"src/components/system/SystemManager.tsx:307:11",...j.settingsTabProps})})]})]})}export{gt as SystemManager};