141 lines
4.5 KiB
Go
141 lines
4.5 KiB
Go
|
|
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
|
|||
|
|
}
|