From 937e8db77647c923c7ce8619061d811e58313c84 Mon Sep 17 00:00:00 2001 From: SunCheng Date: Wed, 21 Jan 2026 19:51:41 +0800 Subject: [PATCH] fix bugs --- Service/Budget/BudgetService.cs | 44 +++++++++++++++++++------------- Web/src/views/StatisticsView.vue | 1 - 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Service/Budget/BudgetService.cs b/Service/Budget/BudgetService.cs index 18ba65f..f7da49c 100644 --- a/Service/Budget/BudgetService.cs +++ b/Service/Budget/BudgetService.cs @@ -192,6 +192,14 @@ public class BudgetService( decimal totalCurrent = 0; decimal totalLimit = 0; + // 是否可以使用趋势统计来计算实际发生额(避免多预算重复计入同一笔账) + var transactionType = category switch + { + BudgetCategory.Expense => TransactionType.Expense, + BudgetCategory.Income => TransactionType.Income, + _ => TransactionType.None + }; + foreach (var budget in relevant) { // 限额折算 @@ -208,7 +216,7 @@ public class BudgetService( } totalLimit += itemLimit; - // 当前值累加 + // 先逐预算累加当前值(作为后备值) var selectedCategories = string.Join(',', budget.SelectedCategories); var currentAmount = await CalculateCurrentAmountAsync(new() { @@ -220,34 +228,21 @@ public class BudgetService( StartDate = new DateTime(referenceDate.Year, referenceDate.Month, 1), IsMandatoryExpense = budget.IsMandatoryExpense }, referenceDate); + if (budget.Type == statType) { totalCurrent += currentAmount; } - else + else if (statType == BudgetPeriodType.Year && budget.Type == BudgetPeriodType.Month) { - // 如果周期不匹配 - if (statType == BudgetPeriodType.Year && budget.Type == BudgetPeriodType.Month) - { - // 在年度视图下,月度预算计入其当前值(作为对年度目前的贡献) - totalCurrent += currentAmount; - } - // 月度视图下,年度预算的 current 不计入 + // 年度视图下,月度预算计入其当前值(作为对年度目前的贡献) + totalCurrent += currentAmount; } } result.Limit = totalLimit; - result.Current = totalCurrent; - result.Rate = totalLimit > 0 ? totalCurrent / totalLimit * 100 : 0; // 计算每日/每月趋势 - var transactionType = category switch - { - BudgetCategory.Expense => TransactionType.Expense, - BudgetCategory.Income => TransactionType.Income, - _ => TransactionType.None - }; - if (transactionType != TransactionType.None) { var hasGlobalBudget = relevant.Any(b => b.SelectedCategories.Length == 0); @@ -283,6 +278,7 @@ public class BudgetService( groupByMonth); decimal accumulated = 0; + decimal lastValidAccumulated = 0; var now = dateTimeProvider.Now; if (statType == BudgetPeriodType.Month) @@ -300,6 +296,7 @@ public class BudgetService( if (dailyStats.TryGetValue(currentDate.Date, out var amount)) { accumulated += amount; + lastValidAccumulated = accumulated; } result.Trend.Add(accumulated); } @@ -319,12 +316,23 @@ public class BudgetService( if (dailyStats.TryGetValue(currentMonthDate, out var amount)) { accumulated += amount; + lastValidAccumulated = accumulated; } result.Trend.Add(accumulated); } } + + // 如果有有效的趋势数据,使用去重后的实际发生额(趋势的累计值),避免同一账单被多预算重复计入 + // 否则使用前面逐预算累加的值(作为后备) + if (lastValidAccumulated > 0) + { + totalCurrent = lastValidAccumulated; + } } + result.Current = totalCurrent; + result.Rate = totalLimit > 0 ? totalCurrent / totalLimit * 100 : 0; + return result; } diff --git a/Web/src/views/StatisticsView.vue b/Web/src/views/StatisticsView.vue index 94d2f44..908682a 100644 --- a/Web/src/views/StatisticsView.vue +++ b/Web/src/views/StatisticsView.vue @@ -1412,7 +1412,6 @@ onBeforeUnmount(() => { .balance-chart { border-radius: 8px; - background: rgba(0, 0, 0, 0.02); padding: 10px 0; margin: 0 -12px; }