package handler import ( "strconv" "time" "carrot_bbs/internal/dto" "carrot_bbs/internal/pkg/response" "carrot_bbs/internal/service" "github.com/gin-gonic/gin" ) // AdminLogHandler 管理后台日志处理器 type AdminLogHandler struct { operationLogService service.OperationLogService loginLogService service.LoginLogService dataChangeLogService service.DataChangeLogService } // NewAdminLogHandler 创建管理后台日志处理器 func NewAdminLogHandler( operationLogService service.OperationLogService, loginLogService service.LoginLogService, dataChangeLogService service.DataChangeLogService, ) *AdminLogHandler { return &AdminLogHandler{ operationLogService: operationLogService, loginLogService: loginLogService, dataChangeLogService: dataChangeLogService, } } // GetOperationLogs 获取操作日志列表 // GET /api/v1/admin/logs/operations func (h *AdminLogHandler) GetOperationLogs(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) filters := dto.LogFilter{ UserID: c.Query("user_id"), Operation: c.Query("operation"), TargetType: c.Query("target_type"), TargetID: c.Query("target_id"), Status: c.Query("status"), IP: c.Query("ip"), StartTime: c.Query("start_time"), EndTime: c.Query("end_time"), } logs, total, err := h.operationLogService.GetOperationLogs(c.Request.Context(), filters, page, pageSize) if err != nil { response.HandleError(c, err, "failed to get operation logs") return } response.Success(c, gin.H{ "logs": logs, "pagination": gin.H{ "page": page, "page_size": pageSize, "total": total, }, }) } // GetLoginLogs 获取登录日志列表 // GET /api/v1/admin/logs/logins func (h *AdminLogHandler) GetLoginLogs(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) filters := dto.LoginFilter{ UserID: c.Query("user_id"), Event: c.Query("event"), Result: c.Query("result"), FailReason: c.Query("fail_reason"), LoginType: c.Query("login_type"), IP: c.Query("ip"), } if startTime := c.Query("start_time"); startTime != "" { if t, err := time.Parse(time.RFC3339, startTime); err == nil { filters.StartTime = t } } if endTime := c.Query("end_time"); endTime != "" { if t, err := time.Parse(time.RFC3339, endTime); err == nil { filters.EndTime = t } } logs, total, err := h.loginLogService.GetLoginLogs(c.Request.Context(), filters, page, pageSize) if err != nil { response.HandleError(c, err, "failed to get login logs") return } response.Success(c, gin.H{ "logs": logs, "pagination": gin.H{ "page": page, "page_size": pageSize, "total": total, }, }) } // GetDataChangeLogs 获取数据变更日志列表 // GET /api/v1/admin/logs/data-changes func (h *AdminLogHandler) GetDataChangeLogs(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) filters := dto.DataChangeFilter{ UserID: c.Query("user_id"), OperatorID: c.Query("operator_id"), ChangeType: c.Query("change_type"), TargetType: c.Query("target_type"), OperatorType: c.Query("operator_type"), IP: c.Query("ip"), StartTime: c.Query("start_time"), EndTime: c.Query("end_time"), } logs, total, err := h.dataChangeLogService.GetDataChangeLogs(c.Request.Context(), filters, page, pageSize) if err != nil { response.HandleError(c, err, "failed to get data change logs") return } response.Success(c, gin.H{ "logs": logs, "pagination": gin.H{ "page": page, "page_size": pageSize, "total": total, }, }) } // GetLogStatistics 获取日志统计 // GET /api/v1/admin/logs/statistics func (h *AdminLogHandler) GetLogStatistics(c *gin.Context) { startTime := c.DefaultQuery("start_time", "") endTime := c.DefaultQuery("end_time", "") operationStats, err := h.operationLogService.GetStatistics(c.Request.Context(), startTime, endTime) if err != nil { response.HandleError(c, err, "failed to get operation log statistics") return } loginStats, err := h.loginLogService.GetStatistics(c.Request.Context(), startTime, endTime) if err != nil { response.HandleError(c, err, "failed to get login log statistics") return } dataChangeStats, err := h.dataChangeLogService.GetStatistics(c.Request.Context(), startTime, endTime) if err != nil { response.HandleError(c, err, "failed to get data change log statistics") return } response.Success(c, gin.H{ "operation_logs": operationStats, "login_logs": loginStats, "data_change_logs": dataChangeStats, }) } // ExportLogs 导出日志 // GET /api/v1/admin/logs/export func (h *AdminLogHandler) ExportLogs(c *gin.Context) { logType := c.Query("type") startTime := c.Query("start_time") endTime := c.Query("end_time") switch logType { case "operation": logs, _, err := h.operationLogService.GetOperationLogsByTimeRange(c.Request.Context(), startTime, endTime, 1, 10000) if err != nil { response.HandleError(c, err, "failed to export operation logs") return } response.Success(c, gin.H{ "type": "operation", "logs": logs, }) case "login": logs, _, err := h.loginLogService.GetLoginLogs(c.Request.Context(), dto.LoginFilter{}, 1, 10000) if err != nil { response.HandleError(c, err, "failed to export login logs") return } response.Success(c, gin.H{ "type": "login", "log": logs, }) case "data_change": logs, _, err := h.dataChangeLogService.GetDataChangeLogs(c.Request.Context(), dto.DataChangeFilter{}, 1, 10000) if err != nil { response.HandleError(c, err, "failed to export data change logs") return } response.Success(c, gin.H{ "type": "data_change", "log": logs, }) default: response.Error(c, 400, "invalid log type") } }