package repository import ( "context" "with_you/internal/dto" "with_you/internal/model" "gorm.io/gorm" ) // OperationLogRepository 操作日志仓储接口 type OperationLogRepository interface { CreateOperationLog(ctx context.Context, log *model.OperationLog) error BatchCreateOperationLogs(ctx context.Context, logs []*model.OperationLog) error GetOperationLogs(ctx context.Context, filters dto.LogFilter, page, pageSize int) ([]*model.OperationLog, int64, error) GetOperationLogsByUser(ctx context.Context, userID string, page, pageSize int) ([]*model.OperationLog, int64, error) GetOperationLogsByTimeRange(ctx context.Context, startTime, endTime string, page, pageSize int) ([]*model.OperationLog, int64, error) DeleteOldLogs(ctx context.Context, beforeDate string) error GetStatistics(ctx context.Context, startTime, endTime string) (*OperationLogStatistics, error) } // operationLogRepository 操作日志仓储实现 type operationLogRepository struct { db *gorm.DB } // NewOperationLogRepository 创建操作日志仓储 func NewOperationLogRepository(db *gorm.DB) OperationLogRepository { return &operationLogRepository{db: db} } // CreateOperationLog 创建单条操作日志 func (r *operationLogRepository) CreateOperationLog(ctx context.Context, log *model.OperationLog) error { return r.db.WithContext(ctx).Create(log).Error } // BatchCreateOperationLogs 批量创建操作日志 func (r *operationLogRepository) BatchCreateOperationLogs(ctx context.Context, logs []*model.OperationLog) error { if len(logs) == 0 { return nil } return r.db.WithContext(ctx).Create(logs).Error } // GetOperationLogs 获取操作日志列表(分页) func (r *operationLogRepository) GetOperationLogs(ctx context.Context, filters dto.LogFilter, page, pageSize int) ([]*model.OperationLog, int64, error) { query := r.db.WithContext(ctx).Model(&model.OperationLog{}) if filters.UserID != "" { query = query.Where("user_id = ?", filters.UserID) } if filters.Operation != "" { query = query.Where("operation = ?", filters.Operation) } if filters.TargetType != "" { query = query.Where("target_type = ?", filters.TargetType) } if filters.TargetID != "" { query = query.Where("target_id = ?", filters.TargetID) } if filters.Status != "" { query = query.Where("status = ?", filters.Status) } if filters.StartTime != "" { query = query.Where("occurred_at >= ?", filters.StartTime) } if filters.EndTime != "" { query = query.Where("occurred_at <= ?", filters.EndTime) } if filters.IP != "" { query = query.Where("ip = ?", filters.IP) } var total int64 if err := query.Count(&total).Error; err != nil { return nil, 0, err } var logs []*model.OperationLog offset := (page - 1) * pageSize if err := query.Order("occurred_at DESC").Offset(offset).Limit(pageSize).Find(&logs).Error; err != nil { return nil, 0, err } return logs, total, nil } // GetOperationLogsByUser 获取指定用户的操作日志 func (r *operationLogRepository) GetOperationLogsByUser(ctx context.Context, userID string, page, pageSize int) ([]*model.OperationLog, int64, error) { return r.GetOperationLogs(ctx, dto.LogFilter{UserID: userID}, page, pageSize) } // GetOperationLogsByTimeRange 按时间范围获取操作日志 func (r *operationLogRepository) GetOperationLogsByTimeRange(ctx context.Context, startTime, endTime string, page, pageSize int) ([]*model.OperationLog, int64, error) { return r.GetOperationLogs(ctx, dto.LogFilter{StartTime: startTime, EndTime: endTime}, page, pageSize) } // DeleteOldLogs 删除旧的操作日志(用于定时清理) func (r *operationLogRepository) DeleteOldLogs(ctx context.Context, beforeDate string) error { return r.db.WithContext(ctx).Where("created_at < ?", beforeDate).Delete(&model.OperationLog{}).Error } // GetStatistics 获取操作日志统计(使用单次 GROUP BY 查询,避免多次 COUNT) func (r *operationLogRepository) GetStatistics(ctx context.Context, startTime, endTime string) (*OperationLogStatistics, error) { stats := &OperationLogStatistics{} query := r.db.WithContext(ctx).Model(&model.OperationLog{}) if startTime != "" { query = query.Where("created_at >= ?", startTime) } if endTime != "" { query = query.Where("created_at <= ?", endTime) } // 使用单次 GROUP BY 查询获取各状态计数 type statusCount struct { Status string Count int64 } var results []statusCount err := query.Select("status, count(*) as count").Group("status").Scan(&results).Error if err != nil { return nil, err } // 汇总结果 for _, r := range results { stats.TotalCount += r.Count switch r.Status { case "success": stats.SuccessCount = r.Count case "fail": stats.FailCount = r.Count } } return stats, nil } // OperationLogStatistics 操作日志统计 type OperationLogStatistics struct { TotalCount int64 SuccessCount int64 FailCount int64 }