feat(预算): 添加预算趋势分析功能并优化图表展示
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 38s
Docker Build & Deploy / Deploy to Production (push) Successful in 10s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 38s
Docker Build & Deploy / Deploy to Production (push) Successful in 10s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
重构预算分析图表组件,添加每日/每月趋势统计功能: 1. 在Repository层添加趋势统计接口 2. 在Service层实现趋势数据计算逻辑 3. 优化前端图表展示,合并偏差分析图表 4. 改进燃尽图使用实际趋势数据 5. 调整UI样式和交互体验
This commit is contained in:
@@ -230,6 +230,91 @@ public class BudgetService(
|
||||
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 == null || b.SelectedCategories.Length == 0);
|
||||
|
||||
var allClassifies = hasGlobalBudget
|
||||
? new List<string>()
|
||||
: relevant
|
||||
.SelectMany(b => b.SelectedCategories)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
DateTime startDate, endDate;
|
||||
bool groupByMonth = false;
|
||||
|
||||
if (statType == BudgetPeriodType.Month)
|
||||
{
|
||||
startDate = new DateTime(referenceDate.Year, referenceDate.Month, 1);
|
||||
endDate = startDate.AddMonths(1).AddDays(-1);
|
||||
groupByMonth = false;
|
||||
}
|
||||
else // Year
|
||||
{
|
||||
startDate = new DateTime(referenceDate.Year, 1, 1);
|
||||
endDate = startDate.AddYears(1).AddDays(-1);
|
||||
groupByMonth = true;
|
||||
}
|
||||
|
||||
var dailyStats = await transactionRecordRepository.GetFilteredTrendStatisticsAsync(
|
||||
startDate,
|
||||
endDate,
|
||||
transactionType,
|
||||
allClassifies,
|
||||
groupByMonth);
|
||||
|
||||
decimal accumulated = 0;
|
||||
var now = DateTime.Now;
|
||||
|
||||
if (statType == BudgetPeriodType.Month)
|
||||
{
|
||||
var daysInMonth = DateTime.DaysInMonth(startDate.Year, startDate.Month);
|
||||
for (int i = 1; i <= daysInMonth; i++)
|
||||
{
|
||||
var currentDate = new DateTime(startDate.Year, startDate.Month, i);
|
||||
if (currentDate.Date > now.Date)
|
||||
{
|
||||
result.Trend.Add(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dailyStats.TryGetValue(currentDate.Date, out var amount))
|
||||
{
|
||||
accumulated += amount;
|
||||
}
|
||||
result.Trend.Add(accumulated);
|
||||
}
|
||||
}
|
||||
else // Year
|
||||
{
|
||||
for (int i = 1; i <= 12; i++)
|
||||
{
|
||||
var currentMonthDate = new DateTime(startDate.Year, i, 1);
|
||||
|
||||
if (currentMonthDate.Year > now.Year || (currentMonthDate.Year == now.Year && i > now.Month))
|
||||
{
|
||||
result.Trend.Add(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dailyStats.TryGetValue(currentMonthDate, out var amount))
|
||||
{
|
||||
accumulated += amount;
|
||||
}
|
||||
result.Trend.Add(accumulated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -896,6 +981,11 @@ public class BudgetStatsDto
|
||||
/// 预算项数量
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每日/每月累计金额趋势(对应当前周期内的实际发生额累计值)
|
||||
/// </summary>
|
||||
public List<decimal?> Trend { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user