package repository import ( "context" "time" "gorm.io/gorm" "github.com/user-management-system/internal/domain" ) // LoginLogRepository 登录日志仓储 type LoginLogRepository struct { db *gorm.DB } // NewLoginLogRepository 创建登录日志仓储 func NewLoginLogRepository(db *gorm.DB) *LoginLogRepository { return &LoginLogRepository{db: db} } // Create 创建登录日志 func (r *LoginLogRepository) Create(ctx context.Context, log *domain.LoginLog) error { return r.db.WithContext(ctx).Create(log).Error } // GetByID 根据ID获取登录日志 func (r *LoginLogRepository) GetByID(ctx context.Context, id int64) (*domain.LoginLog, error) { var log domain.LoginLog if err := r.db.WithContext(ctx).First(&log, id).Error; err != nil { return nil, err } return &log, nil } // ListByUserID 获取用户的登录日志列表 func (r *LoginLogRepository) ListByUserID(ctx context.Context, userID int64, offset, limit int) ([]*domain.LoginLog, int64, error) { var logs []*domain.LoginLog var total int64 query := r.db.WithContext(ctx).Model(&domain.LoginLog{}).Where("user_id = ?", userID) if err := query.Count(&total).Error; err != nil { return nil, 0, err } if err := query.Order("created_at DESC").Offset(offset).Limit(limit).Find(&logs).Error; err != nil { return nil, 0, err } return logs, total, nil } // List 获取登录日志列表(管理员用) func (r *LoginLogRepository) List(ctx context.Context, offset, limit int) ([]*domain.LoginLog, int64, error) { var logs []*domain.LoginLog var total int64 query := r.db.WithContext(ctx).Model(&domain.LoginLog{}) if err := query.Count(&total).Error; err != nil { return nil, 0, err } if err := query.Order("created_at DESC").Offset(offset).Limit(limit).Find(&logs).Error; err != nil { return nil, 0, err } return logs, total, nil } // ListByStatus 按状态查询登录日志 func (r *LoginLogRepository) ListByStatus(ctx context.Context, status int, offset, limit int) ([]*domain.LoginLog, int64, error) { var logs []*domain.LoginLog var total int64 query := r.db.WithContext(ctx).Model(&domain.LoginLog{}).Where("status = ?", status) if err := query.Count(&total).Error; err != nil { return nil, 0, err } if err := query.Order("created_at DESC").Offset(offset).Limit(limit).Find(&logs).Error; err != nil { return nil, 0, err } return logs, total, nil } // ListByTimeRange 按时间范围查询登录日志 func (r *LoginLogRepository) ListByTimeRange(ctx context.Context, start, end time.Time, offset, limit int) ([]*domain.LoginLog, int64, error) { var logs []*domain.LoginLog var total int64 query := r.db.WithContext(ctx).Model(&domain.LoginLog{}). Where("created_at >= ? AND created_at <= ?", start, end) if err := query.Count(&total).Error; err != nil { return nil, 0, err } if err := query.Order("created_at DESC").Offset(offset).Limit(limit).Find(&logs).Error; err != nil { return nil, 0, err } return logs, total, nil } // DeleteByUserID 删除用户所有登录日志 func (r *LoginLogRepository) DeleteByUserID(ctx context.Context, userID int64) error { return r.db.WithContext(ctx).Where("user_id = ?", userID).Delete(&domain.LoginLog{}).Error } // DeleteOlderThan 删除指定天数前的日志 func (r *LoginLogRepository) DeleteOlderThan(ctx context.Context, days int) error { cutoff := time.Now().AddDate(0, 0, -days) return r.db.WithContext(ctx).Where("created_at < ?", cutoff).Delete(&domain.LoginLog{}).Error } // CountByResultSince 统计指定时间之后特定结果的登录次数 // success=true 统计成功次数,false 统计失败次数 func (r *LoginLogRepository) CountByResultSince(ctx context.Context, success bool, since time.Time) int64 { status := 0 // 失败 if success { status = 1 // 成功 } var count int64 r.db.WithContext(ctx).Model(&domain.LoginLog{}). Where("status = ? AND created_at >= ?", status, since). Count(&count) return count } // ListAllForExport 获取所有登录日志(用于导出,无分页) func (r *LoginLogRepository) ListAllForExport(ctx context.Context, userID int64, status int, startAt, endAt *time.Time) ([]*domain.LoginLog, error) { var logs []*domain.LoginLog query := r.db.WithContext(ctx).Model(&domain.LoginLog{}) if userID > 0 { query = query.Where("user_id = ?", userID) } if status == 0 || status == 1 { query = query.Where("status = ?", status) } if startAt != nil { query = query.Where("created_at >= ?", startAt) } if endAt != nil { query = query.Where("created_at <= ?", endAt) } if err := query.Order("created_at DESC").Find(&logs).Error; err != nil { return nil, err } return logs, nil }