package service import ( "filestoragesystem/internal/config" "filestoragesystem/internal/repository" "filestoragesystem/pkg/apperr" ) // StatsService 存储与流量统计服务 type StatsService struct { cfg *config.Config userRepo *repository.UserRepo projectRepo *repository.ProjectRepo fileRepo *repository.FileRepo trafficRepo *repository.TrafficRepo } // UserStats 用户存储统计:总体 + 项目明细 + 流量汇总 func (s *StatsService) UserStats(userID uint) (map[string]interface{}, error) { user, err := s.userRepo.FindByID(userID) if err != nil { return nil, err } fileCount, totalSize, err := s.fileRepo.StatsByUser(userID) if err != nil { return nil, err } projects, err := s.projectRepo.ListByUser(userID) if err != nil { return nil, err } projectStats := make([]map[string]interface{}, 0, len(projects)) for _, p := range projects { count, size, err := s.fileRepo.StatsByProject(p.ID) if err != nil { continue } projectStats = append(projectStats, map[string]interface{}{ "project_id": p.ID, "name": p.Name, "file_count": count, "storage_used": size, "storage_limit": p.StorageLimit, }) } upload30, download30, _ := s.trafficRepo.SumByUser(userID, 30) uploadAll, downloadAll, _ := s.trafficRepo.SumByUser(userID, 0) return map[string]interface{}{ "storage_used": user.StorageUsed, "storage_limit": user.StorageLimit, "file_count": fileCount, "total_size": totalSize, "project_count": len(projects), "projects": projectStats, "traffic": map[string]interface{}{ "upload_30d": upload30, "download_30d": download30, "upload_total": uploadAll, "download_total": downloadAll, }, }, nil } // ProjectStats 项目存储统计 func (s *StatsService) ProjectStats(userID uint, projectID uint, isAdmin bool) (map[string]interface{}, error) { p, err := s.projectRepo.FindByID(projectID) if err != nil { return nil, err } if !isAdmin && p.UserID != userID { return nil, apperr.ErrForbidden } count, size, err := s.fileRepo.StatsByProject(projectID) if err != nil { return nil, err } var trashed int64 s.fileRepo.DB.Table("files").Where("project_id = ? AND status = 0", projectID).Count(&trashed) return map[string]interface{}{ "project_id": p.ID, "name": p.Name, "file_count": count, "storage_used": size, "storage_limit": p.StorageLimit, "trash_count": trashed, }, nil } // TrafficStats 流量统计:按天聚合 + 汇总 func (s *StatsService) TrafficStats(userID uint, days int) (map[string]interface{}, error) { if days <= 0 { days = 30 } daily, err := s.trafficRepo.DailyStats(userID, days) if err != nil { return nil, err } upload, download, _ := s.trafficRepo.SumByUser(userID, days) return map[string]interface{}{ "days": days, "daily": daily, "upload": upload, "download": download, }, nil }