feat: 添加预算管理功能,包括其handler、service和repository层。

This commit is contained in:
2026-02-02 13:55:41 +08:00
parent d08f7902c9
commit 4b2355deee
3 changed files with 75 additions and 3 deletions

View File

@@ -126,6 +126,65 @@ func (s *BudgetService) GetAllBudgets(userID uint) ([]models.Budget, error) {
return budgets, nil
}
// BudgetWithProgress represents a budget with calculated progress fields
type BudgetWithProgress struct {
models.Budget
Spent float64 `json:"spent"`
Progress float64 `json:"progress"`
}
// GetAllBudgetsWithProgress retrieves all budgets with calculated spent and progress for a user
func (s *BudgetService) GetAllBudgetsWithProgress(userID uint) ([]BudgetWithProgress, error) {
budgets, err := s.repo.GetAll(userID)
if err != nil {
return nil, fmt.Errorf("failed to get budgets: %w", err)
}
result := make([]BudgetWithProgress, len(budgets))
now := time.Now()
for i, budget := range budgets {
// Calculate current period
startDate, endDate := s.calculateCurrentPeriod(&budget, now)
// Get spent amount for current period
spent, err := s.repo.GetSpentAmount(&budget, startDate, endDate)
if err != nil {
// Log error but continue with 0 spent
spent = 0
}
// Calculate effective amount and progress
effectiveAmount := budget.Amount
if budget.IsRolling {
// For rolling budgets, calculate effective amount
periodsElapsed := s.calculatePeriodsElapsed(&budget, startDate)
totalBudget := budget.Amount * float64(periodsElapsed+1)
historyEnd := startDate.Add(-time.Second)
historySpent := 0.0
if historyEnd.After(budget.StartDate) {
historySpent, _ = s.repo.GetSpentAmount(&budget, budget.StartDate, historyEnd)
}
effectiveAmount = totalBudget - historySpent
}
progress := 0.0
if effectiveAmount > 0 {
progress = (spent / effectiveAmount) * 100
}
result[i] = BudgetWithProgress{
Budget: budget,
Spent: spent,
Progress: progress,
}
}
return result, nil
}
// UpdateBudget updates an existing budget after verifying ownership
func (s *BudgetService) UpdateBudget(userID, id uint, input BudgetInput) (*models.Budget, error) {
// Get existing budget