优化代码位置
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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"` // 结果详情,如失败时的错误信息
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user