package service import ( "context" "time" "github.com/user-management-system/internal/domain" "github.com/user-management-system/internal/repository" ) // StatsService 统计服务 type StatsService struct { userRepo *repository.UserRepository loginLogRepo *repository.LoginLogRepository } // NewStatsService 创建统计服务 func NewStatsService( userRepo *repository.UserRepository, loginLogRepo *repository.LoginLogRepository, ) *StatsService { return &StatsService{ userRepo: userRepo, loginLogRepo: loginLogRepo, } } // UserStats 用户统计数据 type UserStats struct { TotalUsers int64 `json:"total_users"` ActiveUsers int64 `json:"active_users"` InactiveUsers int64 `json:"inactive_users"` LockedUsers int64 `json:"locked_users"` DisabledUsers int64 `json:"disabled_users"` NewUsersToday int64 `json:"new_users_today"` NewUsersWeek int64 `json:"new_users_week"` NewUsersMonth int64 `json:"new_users_month"` } // LoginStats 登录统计数据 type LoginStats struct { LoginsTodaySuccess int64 `json:"logins_today_success"` LoginsTodayFailed int64 `json:"logins_today_failed"` LoginsWeek int64 `json:"logins_week"` } // DashboardStats 仪表盘综合统计 type DashboardStats struct { Users UserStats `json:"users"` Logins LoginStats `json:"logins"` } // GetUserStats 获取用户统计 func (s *StatsService) GetUserStats(ctx context.Context) (*UserStats, error) { stats := &UserStats{} // 统计总用户数 _, total, err := s.userRepo.List(ctx, 0, 1) if err != nil { return nil, err } stats.TotalUsers = total // 按状态统计 statusCounts := map[domain.UserStatus]*int64{ domain.UserStatusActive: &stats.ActiveUsers, domain.UserStatusInactive: &stats.InactiveUsers, domain.UserStatusLocked: &stats.LockedUsers, domain.UserStatusDisabled: &stats.DisabledUsers, } for status, countPtr := range statusCounts { _, cnt, err := s.userRepo.ListByStatus(ctx, status, 0, 1) if err == nil { *countPtr = cnt } } // 今日新增 stats.NewUsersToday = s.countNewUsers(ctx, daysAgo(0)) // 本周新增 stats.NewUsersWeek = s.countNewUsers(ctx, daysAgo(7)) // 本月新增 stats.NewUsersMonth = s.countNewUsers(ctx, daysAgo(30)) return stats, nil } // countNewUsers 统计指定时间之后的新增用户数 func (s *StatsService) countNewUsers(ctx context.Context, since time.Time) int64 { _, count, err := s.userRepo.ListCreatedAfter(ctx, since, 0, 0) if err != nil { return 0 } return count } // GetDashboardStats 获取仪表盘综合统计 func (s *StatsService) GetDashboardStats(ctx context.Context) (*DashboardStats, error) { userStats, err := s.GetUserStats(ctx) if err != nil { return nil, err } loginStats := &LoginStats{} // 今日登录成功/失败 today := daysAgo(0) if s.loginLogRepo != nil { loginStats.LoginsTodaySuccess = s.loginLogRepo.CountByResultSince(ctx, true, today) loginStats.LoginsTodayFailed = s.loginLogRepo.CountByResultSince(ctx, false, today) loginStats.LoginsWeek = s.loginLogRepo.CountByResultSince(ctx, true, daysAgo(7)) } return &DashboardStats{ Users: *userStats, Logins: *loginStats, }, nil } // daysAgo 返回N天前的时间(当天0点) func daysAgo(n int) time.Time { now := time.Now() start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) return start.AddDate(0, 0, -n) }