mirror of
https://github.com/Awuqing/BackupX.git
synced 2026-05-11 18:10:23 +08:00
110 lines
4.3 KiB
Go
110 lines
4.3 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"backupx/server/internal/apperror"
|
|
"backupx/server/internal/repository"
|
|
)
|
|
|
|
type DashboardStorageUsageItem struct {
|
|
StorageTargetID uint `json:"storageTargetId"`
|
|
TargetName string `json:"targetName"`
|
|
TotalSize int64 `json:"totalSize"`
|
|
}
|
|
|
|
type DashboardStats struct {
|
|
TotalTasks int64 `json:"totalTasks"`
|
|
EnabledTasks int64 `json:"enabledTasks"`
|
|
TotalRecords int64 `json:"totalRecords"`
|
|
SuccessRate float64 `json:"successRate"`
|
|
TotalBackupBytes int64 `json:"totalBackupBytes"`
|
|
LastBackupAt *time.Time `json:"lastBackupAt,omitempty"`
|
|
RecentRecords []BackupRecordSummary `json:"recentRecords"`
|
|
StorageUsage []DashboardStorageUsageItem `json:"storageUsage"`
|
|
}
|
|
|
|
type DashboardService struct {
|
|
tasks repository.BackupTaskRepository
|
|
records repository.BackupRecordRepository
|
|
targets repository.StorageTargetRepository
|
|
}
|
|
|
|
func NewDashboardService(tasks repository.BackupTaskRepository, records repository.BackupRecordRepository, targets repository.StorageTargetRepository) *DashboardService {
|
|
return &DashboardService{tasks: tasks, records: records, targets: targets}
|
|
}
|
|
|
|
func (s *DashboardService) Stats(ctx context.Context) (*DashboardStats, error) {
|
|
totalTasks, err := s.tasks.Count(ctx)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法统计备份任务数量", err)
|
|
}
|
|
enabledTasks, err := s.tasks.CountEnabled(ctx)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法统计启用任务数量", err)
|
|
}
|
|
totalRecords, err := s.records.Count(ctx)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法统计备份记录数量", err)
|
|
}
|
|
since := time.Now().UTC().AddDate(0, 0, -30)
|
|
recentRecordsCount, err := s.records.CountSince(ctx, since)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法统计最近记录数量", err)
|
|
}
|
|
successRecordsCount, err := s.records.CountSuccessSince(ctx, since)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法统计最近成功记录数量", err)
|
|
}
|
|
totalBackupBytes, err := s.records.SumFileSize(ctx)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法统计备份总量", err)
|
|
}
|
|
recentRecords, err := s.records.ListRecent(ctx, 10)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法获取最近备份记录", err)
|
|
}
|
|
targetList, err := s.targets.List(ctx)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法获取存储目标信息", err)
|
|
}
|
|
targetNames := make(map[uint]string, len(targetList))
|
|
for _, item := range targetList {
|
|
targetNames[item.ID] = item.Name
|
|
}
|
|
usageItems, err := s.records.StorageUsage(ctx)
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_STATS_FAILED", "无法统计存储使用量", err)
|
|
}
|
|
storageUsage := make([]DashboardStorageUsageItem, 0, len(usageItems))
|
|
for _, item := range usageItems {
|
|
storageUsage = append(storageUsage, DashboardStorageUsageItem{StorageTargetID: item.StorageTargetID, TargetName: targetNames[item.StorageTargetID], TotalSize: item.TotalSize})
|
|
}
|
|
result := &DashboardStats{TotalTasks: totalTasks, EnabledTasks: enabledTasks, TotalRecords: totalRecords, TotalBackupBytes: totalBackupBytes, RecentRecords: make([]BackupRecordSummary, 0, len(recentRecords)), StorageUsage: storageUsage}
|
|
if recentRecordsCount > 0 {
|
|
result.SuccessRate = float64(successRecordsCount) / float64(recentRecordsCount)
|
|
}
|
|
if len(recentRecords) > 0 {
|
|
result.LastBackupAt = &recentRecords[0].StartedAt
|
|
}
|
|
for _, item := range recentRecords {
|
|
result.RecentRecords = append(result.RecentRecords, toBackupRecordSummary(&item))
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (s *DashboardService) Timeline(ctx context.Context, days int) ([]repository.BackupTimelinePoint, error) {
|
|
if days <= 0 {
|
|
days = 30
|
|
}
|
|
items, err := s.records.TimelineSince(ctx, time.Now().UTC().AddDate(0, 0, -days))
|
|
if err != nil {
|
|
return nil, apperror.Internal("DASHBOARD_TIMELINE_FAILED", "无法获取备份时间线", err)
|
|
}
|
|
if items == nil {
|
|
items = []repository.BackupTimelinePoint{}
|
|
}
|
|
return items, nil
|
|
}
|