diff --git a/internal/app/middleware/audit.go b/internal/app/middleware/audit.go index c57ad3f..bea39f2 100644 --- a/internal/app/middleware/audit.go +++ b/internal/app/middleware/audit.go @@ -7,6 +7,7 @@ import ( "strconv" "git.huangwc.com/pig/pig-farm-controller/internal/app/service/audit" + "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "github.com/gin-gonic/gin" ) @@ -35,6 +36,20 @@ func AuditLogMiddleware(auditService audit.Service) gin.HandlerFunc { return } + // 从 Gin Context 中获取用户对象 + userCtx, userExists := c.Get(repository.ContextUserKey) + var user *models.User + if userExists { + user, _ = userCtx.(*models.User) + } + + // 构建 RequestContext + reqCtx := audit.RequestContext{ + ClientIP: c.ClientIP(), + HTTPPath: c.Request.URL.Path, + HTTPMethod: c.Request.Method, + } + // 获取其他审计信息 description, _ := c.Get(repository.ContextAuditDescription) targetResource, _ := c.Get(repository.ContextAuditTargetResource) @@ -63,7 +78,8 @@ func AuditLogMiddleware(auditService audit.Service) gin.HandlerFunc { // 调用审计服务记录日志(异步) auditService.LogAction( - c, + user, + reqCtx, actionType.(string), description.(string), targetResource, diff --git a/internal/app/middleware/auth.go b/internal/app/middleware/auth.go index 29cc36e..264841c 100644 --- a/internal/app/middleware/auth.go +++ b/internal/app/middleware/auth.go @@ -5,7 +5,6 @@ import ( "net/http" "strings" - "git.huangwc.com/pig/pig-farm-controller/internal/app/service/audit" "git.huangwc.com/pig/pig-farm-controller/internal/app/service/token" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" "github.com/gin-gonic/gin" @@ -53,7 +52,7 @@ func AuthMiddleware(tokenService token.TokenService, userRepo repository.UserRep } // 将完整的用户对象存储在 context 中,以便后续的处理函数使用 - c.Set(audit.ContextUserKey, user) + c.Set(repository.ContextUserKey, user) // 继续处理请求链中的下一个处理程序 c.Next() diff --git a/internal/app/service/audit/service.go b/internal/app/service/audit/service.go index 7412236..bcd6971 100644 --- a/internal/app/service/audit/service.go +++ b/internal/app/service/audit/service.go @@ -7,17 +7,19 @@ import ( "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" - "github.com/gin-gonic/gin" + // 移除对 "github.com/gin-gonic/gin" 的直接依赖 ) -const ( - // ContextUserKey 是存储在 gin.Context 中的用户对象的键名 - ContextUserKey = "user" -) +// RequestContext 封装了审计日志所需的请求上下文信息 +type RequestContext struct { + ClientIP string + HTTPPath string + HTTPMethod string +} // Service 定义了审计服务的接口 type Service interface { - LogAction(c *gin.Context, actionType, description string, targetResource interface{}, status string, resultDetails string) + LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status string, resultDetails string) } // service 是 Service 接口的实现 @@ -32,18 +34,10 @@ func NewService(repo repository.UserActionLogRepository, logger *logs.Logger) Se } // LogAction 记录一个用户操作。它在一个新的 goroutine 中异步执行,以避免阻塞主请求。 -func (s *service) LogAction(c *gin.Context, actionType, description string, targetResource interface{}, status string, resultDetails string) { - // 从 context 中获取预加载的用户信息 - userCtx, exists := c.Get(ContextUserKey) - if !exists { - // 如果上下文中没有用户信息(例如,在未认证的路由上调用了此函数),则不记录日志 - s.logger.Warnw("无法记录审计日志:上下文中缺少用户信息") - return - } - - user, ok := userCtx.(*models.User) - if !ok { - s.logger.Errorw("无法记录审计日志:上下文中的用户对象类型不正确") +func (s *service) LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status string, resultDetails string) { + // 不再从 context 中获取用户信息,直接使用传入的 user 对象 + if user == nil { + s.logger.Warnw("无法记录审计日志:传入的用户对象为 nil") return } @@ -51,12 +45,12 @@ func (s *service) LogAction(c *gin.Context, actionType, description string, targ Time: time.Now(), UserID: user.ID, Username: user.Username, // 用户名快照 - SourceIP: c.ClientIP(), + SourceIP: reqCtx.ClientIP, ActionType: actionType, Description: description, Status: status, - HTTPPath: c.Request.URL.Path, - HTTPMethod: c.Request.Method, + HTTPPath: reqCtx.HTTPPath, + HTTPMethod: reqCtx.HTTPMethod, ResultDetails: resultDetails, } diff --git a/internal/infra/repository/user_action_log_repository.go b/internal/infra/repository/user_action_log_repository.go index 7faa97c..ea20942 100644 --- a/internal/infra/repository/user_action_log_repository.go +++ b/internal/infra/repository/user_action_log_repository.go @@ -13,10 +13,12 @@ const ( ) // --- 审计日志相关上下文键 --- +// TODO 这些变量放这个包合适吗? const ( ContextAuditActionType = "auditActionType" ContextAuditTargetResource = "auditTargetResource" ContextAuditDescription = "auditDescription" + ContextUserKey = "user" // 存储在 gin.Context 中的用户对象的键名 ) // UserActionLogRepository 定义了与用户操作日志相关的数据库操作接口