From fdbea5b7e9feb8c5b9e097c001af39ab69bb5ffe Mon Sep 17 00:00:00 2001 From: huang <1724659546@qq.com> Date: Sun, 28 Sep 2025 01:10:04 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/controller/response.go | 8 +++--- internal/app/middleware/audit.go | 15 ++++++----- internal/app/middleware/auth.go | 3 ++- internal/app/service/audit/service.go | 4 +-- internal/infra/models/execution.go | 25 ++++++++++++++++++- .../repository/user_action_log_repository.go | 15 ----------- 6 files changed, 39 insertions(+), 31 deletions(-) diff --git a/internal/app/controller/response.go b/internal/app/controller/response.go index 5d0c3f3..422026b 100644 --- a/internal/app/controller/response.go +++ b/internal/app/controller/response.go @@ -3,7 +3,7 @@ package controller import ( "net/http" - "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" + "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "github.com/gin-gonic/gin" ) @@ -55,9 +55,9 @@ func SendErrorResponse(ctx *gin.Context, code ResponseCode, message string) { func setAuditDetails(c *gin.Context, actionType, description string, targetResource interface{}) { // 只有当 actionType 不为空时,才设置审计信息,这作为触发审计的标志 if actionType != "" { - c.Set(repository.ContextAuditActionType, actionType) - c.Set(repository.ContextAuditDescription, description) - c.Set(repository.ContextAuditTargetResource, targetResource) + c.Set(models.ContextAuditActionType.String(), actionType) + c.Set(models.ContextAuditDescription.String(), description) + c.Set(models.ContextAuditTargetResource.String(), targetResource) } } diff --git a/internal/app/middleware/audit.go b/internal/app/middleware/audit.go index bea39f2..db2a8b2 100644 --- a/internal/app/middleware/audit.go +++ b/internal/app/middleware/audit.go @@ -8,7 +8,6 @@ import ( "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" ) @@ -30,14 +29,14 @@ func AuditLogMiddleware(auditService audit.Service) gin.HandlerFunc { // --- 在这里,请求已经处理完毕 --- // 从上下文中尝试获取由控制器设置的业务审计信息 - actionType, exists := c.Get(repository.ContextAuditActionType) + actionType, exists := c.Get(models.ContextAuditActionType.String()) if !exists { // 如果上下文中没有 actionType,说明此接口无需记录审计日志,直接返回 return } // 从 Gin Context 中获取用户对象 - userCtx, userExists := c.Get(repository.ContextUserKey) + userCtx, userExists := c.Get(models.ContextUserKey.String()) var user *models.User if userExists { user, _ = userCtx.(*models.User) @@ -51,11 +50,11 @@ func AuditLogMiddleware(auditService audit.Service) gin.HandlerFunc { } // 获取其他审计信息 - description, _ := c.Get(repository.ContextAuditDescription) - targetResource, _ := c.Get(repository.ContextAuditTargetResource) + description, _ := c.Get(models.ContextAuditDescription.String()) + targetResource, _ := c.Get(models.ContextAuditTargetResource.String()) // 默认操作状态为成功 - status := repository.AuditStatusSuccess + status := models.AuditStatusSuccess resultDetails := "" // 尝试从捕获的响应体中解析平台响应 @@ -64,14 +63,14 @@ func AuditLogMiddleware(auditService audit.Service) gin.HandlerFunc { // 如果解析成功,根据平台状态码判断操作是否失败 // 成功状态码范围是 2000-2999 if platformResponse.Code < 2000 || platformResponse.Code >= 3000 { - status = repository.AuditStatusFailed + status = models.AuditStatusFailed resultDetails = platformResponse.Message } } else { // 如果响应体不是预期的平台响应格式,或者解析失败,则记录原始HTTP状态码作为详情 // 并且如果HTTP状态码不是2xx,则标记为失败 if c.Writer.Status() < 200 || c.Writer.Status() >= 300 { - status = repository.AuditStatusFailed + status = models.AuditStatusFailed } resultDetails = "HTTP Status: " + strconv.Itoa(c.Writer.Status()) + ", Body Parse Error: " + err.Error() } diff --git a/internal/app/middleware/auth.go b/internal/app/middleware/auth.go index 264841c..8684acb 100644 --- a/internal/app/middleware/auth.go +++ b/internal/app/middleware/auth.go @@ -6,6 +6,7 @@ import ( "strings" "git.huangwc.com/pig/pig-farm-controller/internal/app/service/token" + "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" "gorm.io/gorm" @@ -52,7 +53,7 @@ func AuthMiddleware(tokenService token.TokenService, userRepo repository.UserRep } // 将完整的用户对象存储在 context 中,以便后续的处理函数使用 - c.Set(repository.ContextUserKey, user) + c.Set(models.ContextUserKey.String(), user) // 继续处理请求链中的下一个处理程序 c.Next() diff --git a/internal/app/service/audit/service.go b/internal/app/service/audit/service.go index bcd6971..6f72396 100644 --- a/internal/app/service/audit/service.go +++ b/internal/app/service/audit/service.go @@ -19,7 +19,7 @@ type RequestContext struct { // Service 定义了审计服务的接口 type Service interface { - LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status string, resultDetails string) + LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status models.AuditStatus, resultDetails string) } // service 是 Service 接口的实现 @@ -34,7 +34,7 @@ func NewService(repo repository.UserActionLogRepository, logger *logs.Logger) Se } // LogAction 记录一个用户操作。它在一个新的 goroutine 中异步执行,以避免阻塞主请求。 -func (s *service) LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status string, resultDetails string) { +func (s *service) LogAction(user *models.User, reqCtx RequestContext, actionType, description string, targetResource interface{}, status models.AuditStatus, resultDetails string) { // 不再从 context 中获取用户信息,直接使用传入的 user 对象 if user == nil { s.logger.Warnw("无法记录审计日志:传入的用户对象为 nil") diff --git a/internal/infra/models/execution.go b/internal/infra/models/execution.go index 90073e7..392187a 100644 --- a/internal/infra/models/execution.go +++ b/internal/infra/models/execution.go @@ -145,6 +145,29 @@ func (PendingCollection) TableName() string { } // --- 用户审计日志 --- +// TODO 这些变量放这个包合适吗? + +// --- 审计日志状态常量 --- +type AuditStatus string + +const ( + AuditStatusSuccess AuditStatus = "success" + AuditStatusFailed AuditStatus = "failed" +) + +// --- 审计日志相关上下文键 --- +type AuditContextKey string + +const ( + ContextAuditActionType AuditContextKey = "auditActionType" + ContextAuditTargetResource AuditContextKey = "auditTargetResource" + ContextAuditDescription AuditContextKey = "auditDescription" + ContextUserKey AuditContextKey = "user" +) + +func (a AuditContextKey) String() string { + return string(a) +} // UserActionLog 记录用户的操作历史,用于审计 type UserActionLog struct { @@ -162,7 +185,7 @@ type UserActionLog struct { ActionType string `gorm:"index" json:"action_type,omitempty"` // 标准化的操作类型,如 "CREATE_DEVICE" TargetResource datatypes.JSON `gorm:"type:jsonb" json:"target_resource,omitempty"` // 被操作的资源, e.g., {"type": "device", "id": 123} Description string `json:"description,omitempty"` // 人类可读的操作描述 - Status string `json:"status,omitempty"` // success 或 failed + Status AuditStatus `json:"status,omitempty"` // success 或 failed HTTPPath string `json:"http_path,omitempty"` // 请求的API路径 HTTPMethod string `json:"http_method,omitempty"` // 请求的HTTP方法 ResultDetails string `json:"result_details,omitempty"` // 结果详情,如失败时的错误信息 diff --git a/internal/infra/repository/user_action_log_repository.go b/internal/infra/repository/user_action_log_repository.go index ea20942..cfaac10 100644 --- a/internal/infra/repository/user_action_log_repository.go +++ b/internal/infra/repository/user_action_log_repository.go @@ -6,21 +6,6 @@ import ( "gorm.io/gorm" ) -// --- 审计日志状态常量 --- -const ( - AuditStatusSuccess = "success" - AuditStatusFailed = "failed" -) - -// --- 审计日志相关上下文键 --- -// TODO 这些变量放这个包合适吗? -const ( - ContextAuditActionType = "auditActionType" - ContextAuditTargetResource = "auditTargetResource" - ContextAuditDescription = "auditDescription" - ContextUserKey = "user" // 存储在 gin.Context 中的用户对象的键名 -) - // UserActionLogRepository 定义了与用户操作日志相关的数据库操作接口 type UserActionLogRepository interface { Create(log *models.UserActionLog) error