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:
1 parent
e57718998a
commit
77c234b060
314 files changed
+10050
-4065
No files matched your search
@@ -2,11 +2,13 @@
|
||||
// 从 services/api.ts 拆分 — Q3 api.ts 模块化
|
||||
|
||||
import { http, type ListResponse } from '../http';
|
||||
import { isOnline, timeAgo, asList } from '../../components/agent/agentUtils';
|
||||
|
||||
export const auditApi = {
|
||||
getLogs: async (params?: { page?: number; page_size?: number; module?: string; action?: string }) => {
|
||||
return http.get<ListResponse>('/audit/logs', params);
|
||||
getLogs: async (params?: { page?: number; page_size?: number; module?: string; action?: string; username?: string; start_time?: string; end_time?: string }) => {
|
||||
return http.get<ListResponse>('/audit/logs', params as Record<string, string | number | boolean | undefined>);
|
||||
},
|
||||
getLogDetail: async (id: number | string) => {
|
||||
return http.get(`/audit/logs/${id}`);
|
||||
},
|
||||
getModules: async () => {
|
||||
return http.get('/audit/modules');
|
||||
@@ -17,6 +19,17 @@ export const auditApi = {
|
||||
getStatistics: async () => {
|
||||
return http.get('/audit/statistics');
|
||||
},
|
||||
exportLogs: async (params?: Record<string, string | number | boolean | undefined>) => {
|
||||
// Build URL with query params for server-side CSV export
|
||||
const qs = new URLSearchParams();
|
||||
qs.set('format', 'csv');
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([k, v]) => {
|
||||
if (v !== undefined && v !== null && v !== '') qs.set(k, String(v));
|
||||
});
|
||||
}
|
||||
return http.download(`/audit/logs/export?${qs.toString()}`);
|
||||
},
|
||||
clearLogs: async () => {
|
||||
return http.post('/audit/logs/clear');
|
||||
},
|
||||
@@ -24,9 +37,51 @@ export const auditApi = {
|
||||
|
||||
// ==================== 终端会话审计 API(WebSSH 录制) ==================== // Logan.Li
|
||||
|
||||
export const terminalSessionApi = {
|
||||
list: async (params?: { page?: number; page_size?: number; server_id?: number; username?: string; status?: string }) => {
|
||||
return http.get<ListResponse>('/terminal-sessions', params as Record<string, string | number | boolean | undefined>);
|
||||
},
|
||||
get: async (id: number) => {
|
||||
return http.get(`/terminal-sessions/${id}`);
|
||||
},
|
||||
getRecord: async (id: number) => {
|
||||
return http.get<string>(`/terminal-sessions/${id}/record`);
|
||||
},
|
||||
kill: async (id: number) => {
|
||||
return http.post(`/terminal-sessions/${id}/kill`);
|
||||
},
|
||||
download: async (id: number) => {
|
||||
return http.download(`/terminal-sessions/${id}/download`, `session-${id}.cast`);
|
||||
},
|
||||
delete: async (id: number) => {
|
||||
return http.delete(`/terminal-sessions/${id}`);
|
||||
},
|
||||
batchDelete: async (ids: number[]) => {
|
||||
return http.post('/terminal-sessions/batch-delete', { ids });
|
||||
},
|
||||
};
|
||||
|
||||
// ==================== 会话命令审计 API ====================
|
||||
|
||||
export const sessionCommandApi = {
|
||||
list: async (params?: { page?: number; page_size?: number; session_id?: number; username?: string }) => {
|
||||
return http.get<ListResponse>('/session-commands', params as Record<string, string | number | boolean | undefined>);
|
||||
},
|
||||
};
|
||||
|
||||
// ==================== 登录日志 API ====================
|
||||
|
||||
export const loginLogApi = {
|
||||
list: async (params?: { page?: number; page_size?: number; username?: string; status?: string }) => {
|
||||
return http.get<ListResponse>('/login-logs', params as Record<string, string | number | boolean | undefined>);
|
||||
},
|
||||
};
|
||||
|
||||
// ==================== 审批流程 API ====================
|
||||
|
||||
export const approvalApi = {
|
||||
getTemplates: async () => {
|
||||
return http.get('/approvals/templates');
|
||||
getTemplates: async (params?: { type?: string; category?: string }) => {
|
||||
return http.get('/approvals/templates', params);
|
||||
},
|
||||
getTemplate: async (id: number | string) => {
|
||||
return http.get(`/approvals/templates/${id}`);
|
||||
@@ -40,7 +95,7 @@ export const approvalApi = {
|
||||
deleteTemplate: async (id: number | string) => {
|
||||
return http.delete(`/approvals/templates/${id}`);
|
||||
},
|
||||
getProcesses: async (params?: { page?: number; page_size?: number; status?: string }) => {
|
||||
getProcesses: async (params?: { page?: number; page_size?: number; status?: string; category?: string }) => {
|
||||
return http.get('/approvals/processes', params);
|
||||
},
|
||||
createProcess: async ( data: any) => {
|
||||
|
||||
Reference in new issue
Block a user