Files

125 lines
3.3 KiB
Go
Raw Permalink Normal View History

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)
}