Fix: Store monthly increments instead of cumulative snapshots

This commit is contained in:
DullJZ
2025-11-03 22:23:12 +08:00
parent dc6916f3df
commit 953feb1965
+65 -19
View File
@@ -631,29 +631,69 @@ func (s *Service) DeleteVirtualBucketFileMapping(virtualBucketName, objectKey st
return nil return nil
} }
// ArchiveMonthlyStats 归档指定月份的统计数据 // ArchiveMonthlyStats 归档指定月份的统计数据(存储增量值,非累计值)
// 如果该月份的记录已存在,则更新;否则创建新记录 // 如果该月份的记录已存在,则更新;否则创建新记录
func (s *Service) ArchiveMonthlyStats(year, month int) error { func (s *Service) ArchiveMonthlyStats(year, month int) error {
var stats []BucketStats // 获取当前所有bucket的累计统计
if err := s.db.Find(&stats).Error; err != nil { var currentStats []BucketStats
if err := s.db.Find(&currentStats).Error; err != nil {
return fmt.Errorf("failed to fetch bucket stats: %w", err) return fmt.Errorf("failed to fetch bucket stats: %w", err)
} }
for _, stat := range stats { // 获取上个月的累计值(从上月归档数据推算)
lastYear, lastMonth := year, month-1
if lastMonth == 0 {
lastMonth = 12
lastYear--
}
// 查询上个月及之前的所有归档数据,用于推算上月末的累计值
var lastMonthArchived []BucketMonthlyStats
lastMonthMap := make(map[string]int64) // bucket_name -> last_month_cumulative_a
lastMonthMapB := make(map[string]int64) // bucket_name -> last_month_cumulative_b
if err := s.db.Where("year < ? OR (year = ? AND month <= ?)", lastYear, lastYear, lastMonth).
Order("year ASC, month ASC").
Find(&lastMonthArchived).Error; err == nil {
// 累加历史增量得到上月末累计值
cumulativeA := make(map[string]int64)
cumulativeB := make(map[string]int64)
for _, archived := range lastMonthArchived {
cumulativeA[archived.BucketName] += archived.OperationCountA
cumulativeB[archived.BucketName] += archived.OperationCountB
}
lastMonthMap = cumulativeA
lastMonthMapB = cumulativeB
}
// 对每个bucket,计算本月增量并存储
for _, stat := range currentStats {
lastCumulativeA := lastMonthMap[stat.BucketName]
lastCumulativeB := lastMonthMapB[stat.BucketName]
incrementA := stat.OperationCountA - lastCumulativeA
incrementB := stat.OperationCountB - lastCumulativeB
// 如果是首次运行(没有历史数据),incrementA/B 可能等于累计值
// 这是预期行为:首月记录的就是从0到当前的增量
monthlyStats := BucketMonthlyStats{ monthlyStats := BucketMonthlyStats{
BucketName: stat.BucketName, BucketName: stat.BucketName,
Year: year, Year: year,
Month: month, Month: month,
OperationCountA: stat.OperationCountA, OperationCountA: incrementA,
OperationCountB: stat.OperationCountB, OperationCountB: incrementB,
} }
// 使用 UPSERT 逻辑:如果存在则更新,否则创建 // 使用 UPSERT 逻辑:如果存在则更新,否则创建
if err := s.db.Where("bucket_name = ? AND year = ? AND month = ?", if err := s.db.Where("bucket_name = ? AND year = ? AND month = ?",
stat.BucketName, year, month). stat.BucketName, year, month).
Assign(BucketMonthlyStats{ Assign(BucketMonthlyStats{
OperationCountA: stat.OperationCountA, OperationCountA: incrementA,
OperationCountB: stat.OperationCountB, OperationCountB: incrementB,
}). }).
FirstOrCreate(&monthlyStats).Error; err != nil { FirstOrCreate(&monthlyStats).Error; err != nil {
return fmt.Errorf("failed to archive monthly stats for bucket %s: %w", stat.BucketName, err) return fmt.Errorf("failed to archive monthly stats for bucket %s: %w", stat.BucketName, err)
@@ -685,24 +725,28 @@ func (s *Service) GetMonthlyStatsRange(startYear, startMonth, endYear, endMonth
return stats, nil return stats, nil
} }
// GetCurrentMonthStats 获取当前月份的实时统计(从 bucket_stats 计算) // GetCurrentMonthStats 获取当前月份的实时统计(从 bucket_stats 计算增量
func (s *Service) GetCurrentMonthStats() ([]BucketMonthlyStats, error) { func (s *Service) GetCurrentMonthStats() ([]BucketMonthlyStats, error) {
now := time.Now() now := time.Now()
year, month := now.Year(), int(now.Month()) year, month := now.Year(), int(now.Month())
// 获取上个月的归档数据 // 获取上个月末的累计值(通过累加所有历史增量)
var lastMonthStats []BucketMonthlyStats
lastYear, lastMonth := year, month-1 lastYear, lastMonth := year, month-1
if lastMonth == 0 { if lastMonth == 0 {
lastMonth = 12 lastMonth = 12
lastYear-- lastYear--
} }
lastMonthMap := make(map[string]BucketMonthlyStats) var historicalStats []BucketMonthlyStats
if err := s.db.Where("year = ? AND month = ?", lastYear, lastMonth). lastMonthCumulativeA := make(map[string]int64)
Find(&lastMonthStats).Error; err == nil { lastMonthCumulativeB := make(map[string]int64)
for _, stat := range lastMonthStats {
lastMonthMap[stat.BucketName] = stat if err := s.db.Where("year < ? OR (year = ? AND month <= ?)", lastYear, lastYear, lastMonth).
Find(&historicalStats).Error; err == nil {
// 累加所有历史增量得到上月末累计值
for _, stat := range historicalStats {
lastMonthCumulativeA[stat.BucketName] += stat.OperationCountA
lastMonthCumulativeB[stat.BucketName] += stat.OperationCountB
} }
} }
@@ -715,13 +759,15 @@ func (s *Service) GetCurrentMonthStats() ([]BucketMonthlyStats, error) {
// 计算当前月份的增量 // 计算当前月份的增量
result := make([]BucketMonthlyStats, 0, len(currentStats)) result := make([]BucketMonthlyStats, 0, len(currentStats))
for _, current := range currentStats { for _, current := range currentStats {
lastMonth := lastMonthMap[current.BucketName] incrementA := current.OperationCountA - lastMonthCumulativeA[current.BucketName]
incrementB := current.OperationCountB - lastMonthCumulativeB[current.BucketName]
result = append(result, BucketMonthlyStats{ result = append(result, BucketMonthlyStats{
BucketName: current.BucketName, BucketName: current.BucketName,
Year: year, Year: year,
Month: month, Month: month,
OperationCountA: current.OperationCountA - lastMonth.OperationCountA, OperationCountA: incrementA,
OperationCountB: current.OperationCountB - lastMonth.OperationCountB, OperationCountB: incrementB,
UpdatedAt: time.Now(), UpdatedAt: time.Now(),
}) })
} }