优化代码位置
This commit is contained in:
@@ -3,7 +3,7 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"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"
|
"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{}) {
|
func setAuditDetails(c *gin.Context, actionType, description string, targetResource interface{}) {
|
||||||
// 只有当 actionType 不为空时,才设置审计信息,这作为触发审计的标志
|
// 只有当 actionType 不为空时,才设置审计信息,这作为触发审计的标志
|
||||||
if actionType != "" {
|
if actionType != "" {
|
||||||
c.Set(repository.ContextAuditActionType, actionType)
|
c.Set(models.ContextAuditActionType.String(), actionType)
|
||||||
c.Set(repository.ContextAuditDescription, description)
|
c.Set(models.ContextAuditDescription.String(), description)
|
||||||
c.Set(repository.ContextAuditTargetResource, targetResource)
|
c.Set(models.ContextAuditTargetResource.String(), targetResource)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/app/service/audit"
|
"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/models"
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
|
||||||
"github.com/gin-gonic/gin"
|
"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 {
|
if !exists {
|
||||||
// 如果上下文中没有 actionType,说明此接口无需记录审计日志,直接返回
|
// 如果上下文中没有 actionType,说明此接口无需记录审计日志,直接返回
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从 Gin Context 中获取用户对象
|
// 从 Gin Context 中获取用户对象
|
||||||
userCtx, userExists := c.Get(repository.ContextUserKey)
|
userCtx, userExists := c.Get(models.ContextUserKey.String())
|
||||||
var user *models.User
|
var user *models.User
|
||||||
if userExists {
|
if userExists {
|
||||||
user, _ = userCtx.(*models.User)
|
user, _ = userCtx.(*models.User)
|
||||||
@@ -51,11 +50,11 @@ func AuditLogMiddleware(auditService audit.Service) gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取其他审计信息
|
// 获取其他审计信息
|
||||||
description, _ := c.Get(repository.ContextAuditDescription)
|
description, _ := c.Get(models.ContextAuditDescription.String())
|
||||||
targetResource, _ := c.Get(repository.ContextAuditTargetResource)
|
targetResource, _ := c.Get(models.ContextAuditTargetResource.String())
|
||||||
|
|
||||||
// 默认操作状态为成功
|
// 默认操作状态为成功
|
||||||
status := repository.AuditStatusSuccess
|
status := models.AuditStatusSuccess
|
||||||
resultDetails := ""
|
resultDetails := ""
|
||||||
|
|
||||||
// 尝试从捕获的响应体中解析平台响应
|
// 尝试从捕获的响应体中解析平台响应
|
||||||
@@ -64,14 +63,14 @@ func AuditLogMiddleware(auditService audit.Service) gin.HandlerFunc {
|
|||||||
// 如果解析成功,根据平台状态码判断操作是否失败
|
// 如果解析成功,根据平台状态码判断操作是否失败
|
||||||
// 成功状态码范围是 2000-2999
|
// 成功状态码范围是 2000-2999
|
||||||
if platformResponse.Code < 2000 || platformResponse.Code >= 3000 {
|
if platformResponse.Code < 2000 || platformResponse.Code >= 3000 {
|
||||||
status = repository.AuditStatusFailed
|
status = models.AuditStatusFailed
|
||||||
resultDetails = platformResponse.Message
|
resultDetails = platformResponse.Message
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果响应体不是预期的平台响应格式,或者解析失败,则记录原始HTTP状态码作为详情
|
// 如果响应体不是预期的平台响应格式,或者解析失败,则记录原始HTTP状态码作为详情
|
||||||
// 并且如果HTTP状态码不是2xx,则标记为失败
|
// 并且如果HTTP状态码不是2xx,则标记为失败
|
||||||
if c.Writer.Status() < 200 || c.Writer.Status() >= 300 {
|
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()
|
resultDetails = "HTTP Status: " + strconv.Itoa(c.Writer.Status()) + ", Body Parse Error: " + err.Error()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/app/service/token"
|
"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"
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -52,7 +53,7 @@ func AuthMiddleware(tokenService token.TokenService, userRepo repository.UserRep
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 将完整的用户对象存储在 context 中,以便后续的处理函数使用
|
// 将完整的用户对象存储在 context 中,以便后续的处理函数使用
|
||||||
c.Set(repository.ContextUserKey, user)
|
c.Set(models.ContextUserKey.String(), user)
|
||||||
|
|
||||||
// 继续处理请求链中的下一个处理程序
|
// 继续处理请求链中的下一个处理程序
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type RequestContext struct {
|
|||||||
|
|
||||||
// Service 定义了审计服务的接口
|
// Service 定义了审计服务的接口
|
||||||
type Service interface {
|
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 接口的实现
|
// service 是 Service 接口的实现
|
||||||
@@ -34,7 +34,7 @@ func NewService(repo repository.UserActionLogRepository, logger *logs.Logger) Se
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LogAction 记录一个用户操作。它在一个新的 goroutine 中异步执行,以避免阻塞主请求。
|
// 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 对象
|
// 不再从 context 中获取用户信息,直接使用传入的 user 对象
|
||||||
if user == nil {
|
if user == nil {
|
||||||
s.logger.Warnw("无法记录审计日志:传入的用户对象为 nil")
|
s.logger.Warnw("无法记录审计日志:传入的用户对象为 nil")
|
||||||
|
|||||||
@@ -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 记录用户的操作历史,用于审计
|
// UserActionLog 记录用户的操作历史,用于审计
|
||||||
type UserActionLog struct {
|
type UserActionLog struct {
|
||||||
@@ -162,7 +185,7 @@ type UserActionLog struct {
|
|||||||
ActionType string `gorm:"index" json:"action_type,omitempty"` // 标准化的操作类型,如 "CREATE_DEVICE"
|
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}
|
TargetResource datatypes.JSON `gorm:"type:jsonb" json:"target_resource,omitempty"` // 被操作的资源, e.g., {"type": "device", "id": 123}
|
||||||
Description string `json:"description,omitempty"` // 人类可读的操作描述
|
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路径
|
HTTPPath string `json:"http_path,omitempty"` // 请求的API路径
|
||||||
HTTPMethod string `json:"http_method,omitempty"` // 请求的HTTP方法
|
HTTPMethod string `json:"http_method,omitempty"` // 请求的HTTP方法
|
||||||
ResultDetails string `json:"result_details,omitempty"` // 结果详情,如失败时的错误信息
|
ResultDetails string `json:"result_details,omitempty"` // 结果详情,如失败时的错误信息
|
||||||
|
|||||||
@@ -6,21 +6,6 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// --- 审计日志状态常量 ---
|
|
||||||
const (
|
|
||||||
AuditStatusSuccess = "success"
|
|
||||||
AuditStatusFailed = "failed"
|
|
||||||
)
|
|
||||||
|
|
||||||
// --- 审计日志相关上下文键 ---
|
|
||||||
// TODO 这些变量放这个包合适吗?
|
|
||||||
const (
|
|
||||||
ContextAuditActionType = "auditActionType"
|
|
||||||
ContextAuditTargetResource = "auditTargetResource"
|
|
||||||
ContextAuditDescription = "auditDescription"
|
|
||||||
ContextUserKey = "user" // 存储在 gin.Context 中的用户对象的键名
|
|
||||||
)
|
|
||||||
|
|
||||||
// UserActionLogRepository 定义了与用户操作日志相关的数据库操作接口
|
// UserActionLogRepository 定义了与用户操作日志相关的数据库操作接口
|
||||||
type UserActionLogRepository interface {
|
type UserActionLogRepository interface {
|
||||||
Create(log *models.UserActionLog) error
|
Create(log *models.UserActionLog) error
|
||||||
|
|||||||
Reference in New Issue
Block a user