From 3c8b91ff6a75589a3307cb49c888947ef80d7e57 Mon Sep 17 00:00:00 2001 From: huang <1724659546@qq.com> Date: Sun, 28 Sep 2025 00:37:20 +0800 Subject: [PATCH] =?UTF-8?q?JSON=E8=BD=AC=E6=8D=A2=E6=94=BE=E5=9C=A8?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E5=87=BD=E6=95=B0=E9=87=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/service/audit/service.go | 38 +++++++++++---------------- internal/infra/models/execution.go | 25 ++++++++++++++++++ 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/internal/app/service/audit/service.go b/internal/app/service/audit/service.go index 105561c..7412236 100644 --- a/internal/app/service/audit/service.go +++ b/internal/app/service/audit/service.go @@ -2,14 +2,12 @@ package audit import ( - "encoding/json" "time" "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" - "gorm.io/datatypes" ) const ( @@ -49,29 +47,23 @@ func (s *service) LogAction(c *gin.Context, actionType, description string, targ return } - // 将 targetResource 转换为 JSONB,如果失败则记录错误但继续 - var targetResourceJSON datatypes.JSON - if targetResource != nil { - bytes, err := json.Marshal(targetResource) - if err != nil { - s.logger.Errorw("无法记录审计日志:序列化 targetResource 失败", "error", err) - } else { - targetResourceJSON = bytes - } + log := &models.UserActionLog{ + Time: time.Now(), + UserID: user.ID, + Username: user.Username, // 用户名快照 + SourceIP: c.ClientIP(), + ActionType: actionType, + Description: description, + Status: status, + HTTPPath: c.Request.URL.Path, + HTTPMethod: c.Request.Method, + ResultDetails: resultDetails, } - log := &models.UserActionLog{ - Time: time.Now(), - UserID: user.ID, - Username: user.Username, // 用户名快照 - SourceIP: c.ClientIP(), - ActionType: actionType, - TargetResource: targetResourceJSON, - Description: description, - Status: status, - HTTPPath: c.Request.URL.Path, - HTTPMethod: c.Request.Method, - ResultDetails: resultDetails, + // 使用模型提供的方法来设置 TargetResource + if err := log.SetTargetResource(targetResource); err != nil { + s.logger.Errorw("无法记录审计日志:序列化 targetResource 失败", "error", err) + // 即使序列化失败,我们可能仍然希望记录操作本身,所以不在此处 return } // 异步写入数据库,不阻塞当前请求 diff --git a/internal/infra/models/execution.go b/internal/infra/models/execution.go index 257dcea..90073e7 100644 --- a/internal/infra/models/execution.go +++ b/internal/infra/models/execution.go @@ -1,6 +1,8 @@ package models import ( + "encoding/json" + "errors" "time" "gorm.io/datatypes" @@ -170,3 +172,26 @@ type UserActionLog struct { func (UserActionLog) TableName() string { return "user_action_logs" } + +// ParseTargetResource 解析 JSON 属性到一个具体的结构体中。 +// 调用方需要传入一个指向目标结构体实例的指针。 +func (l *UserActionLog) ParseTargetResource(v interface{}) error { + if l.TargetResource == nil { + return errors.New("目标资源为空,无法解析") + } + return json.Unmarshal(l.TargetResource, v) +} + +// SetTargetResource 将任意结构体序列化为 JSON 并设置到 TargetResource 字段 +func (l *UserActionLog) SetTargetResource(data interface{}) error { + if data == nil { + l.TargetResource = nil + return nil + } + bytes, err := json.Marshal(data) + if err != nil { + return err + } + l.TargetResource = bytes + return nil +}