feat: backend core - auth, user, role, permission, device, webhook, monitoring, cache, repository, service, middleware, API handlers
This commit is contained in:
124
internal/service/stats.go
Normal file
124
internal/service/stats.go
Normal file
@@ -0,0 +1,124 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user