Files
EmailBill/Application/TransactionStatisticsApplication.cs
SunCheng d052ae5197 fix
2026-02-10 17:49:19 +08:00

204 lines
8.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Application.Dto.Statistics;
using Service.Transaction;
namespace Application;
/// <summary>
/// 交易统计应用服务接口
/// </summary>
public interface ITransactionStatisticsApplication
{
// === 新统一接口(推荐使用) ===
/// <summary>
/// 按日期范围获取每日统计(新统一接口)
/// </summary>
Task<List<DailyStatisticsDto>> GetDailyStatisticsByRangeAsync(DateTime startDate, DateTime endDate, string? savingClassify = null);
/// <summary>
/// 按日期范围获取汇总统计(新统一接口)
/// </summary>
Task<MonthlyStatistics> GetSummaryByRangeAsync(DateTime startDate, DateTime endDate);
/// <summary>
/// 按日期范围获取分类统计(新统一接口)
/// </summary>
Task<List<CategoryStatistics>> GetCategoryStatisticsByRangeAsync(DateTime startDate, DateTime endDate, TransactionType type);
/// <summary>
/// 获取趋势统计数据
/// </summary>
Task<List<TrendStatistics>> GetTrendStatisticsAsync(int startYear, int startMonth, int monthCount);
// === 旧接口(保留用于向后兼容,建议迁移到新接口) ===
[Obsolete("请使用 GetDailyStatisticsByRangeAsync")]
Task<List<BalanceStatisticsDto>> GetBalanceStatisticsAsync(int year, int month);
[Obsolete("请使用 GetDailyStatisticsByRangeAsync")]
Task<List<DailyStatisticsDto>> GetDailyStatisticsAsync(int year, int month);
[Obsolete("请使用 GetDailyStatisticsByRangeAsync")]
Task<List<DailyStatisticsDto>> GetWeeklyStatisticsAsync(DateTime startDate, DateTime endDate);
[Obsolete("请使用 GetSummaryByRangeAsync")]
Task<MonthlyStatistics> GetRangeStatisticsAsync(DateTime startDate, DateTime endDate);
[Obsolete("请使用 GetSummaryByRangeAsync")]
Task<MonthlyStatistics> GetMonthlyStatisticsAsync(int year, int month);
[Obsolete("请使用 GetCategoryStatisticsByRangeAsync")]
Task<List<CategoryStatistics>> GetCategoryStatisticsAsync(int year, int month, TransactionType type);
[Obsolete("请使用 GetCategoryStatisticsByRangeAsync")]
Task<List<CategoryStatistics>> GetCategoryStatisticsByDateRangeAsync(string startDate, string endDate, TransactionType type);
Task<(List<ReasonGroupDto> list, int total)> GetReasonGroupsAsync(int pageIndex, int pageSize);
}
/// <summary>
/// 交易统计应用服务实现
/// </summary>
public class TransactionStatisticsApplication(
ITransactionStatisticsService statisticsService,
IConfigService configService,
ILogger<TransactionStatisticsApplication> logger
) : ITransactionStatisticsApplication
{
// === 新统一接口实现 ===
/// <summary>
/// 按日期范围获取每日统计(新统一接口)
/// </summary>
public async Task<List<DailyStatisticsDto>> GetDailyStatisticsByRangeAsync(DateTime startDate, DateTime endDate, string? savingClassify = null)
{
// 如果未指定 savingClassify从配置读取
savingClassify ??= await configService.GetConfigByKeyAsync<string>("SavingsCategories");
var statistics = await statisticsService.GetDailyStatisticsByRangeAsync(startDate, endDate, savingClassify);
return statistics.Select(s => new DailyStatisticsDto(
DateTime.Parse(s.Key).Day,
s.Value.count,
s.Value.expense,
s.Value.income,
s.Value.saving
)).ToList();
}
/// <summary>
/// 按日期范围获取汇总统计(新统一接口)
/// </summary>
public async Task<MonthlyStatistics> GetSummaryByRangeAsync(DateTime startDate, DateTime endDate)
{
return await statisticsService.GetSummaryByRangeAsync(startDate, endDate);
}
/// <summary>
/// 按日期范围获取分类统计(新统一接口)
/// </summary>
public async Task<List<CategoryStatistics>> GetCategoryStatisticsByRangeAsync(DateTime startDate, DateTime endDate, TransactionType type)
{
return await statisticsService.GetCategoryStatisticsByDateRangeAsync(startDate, endDate, type);
}
// === 旧接口实现(保留用于向后兼容) ===
public async Task<List<BalanceStatisticsDto>> GetBalanceStatisticsAsync(int year, int month)
{
var savingClassify = await configService.GetConfigByKeyAsync<string>("SavingsCategories");
var statistics = await statisticsService.GetDailyStatisticsAsync(year, month, savingClassify);
var sortedStats = statistics.OrderBy(s => DateTime.Parse(s.Key)).ToList();
var result = new List<BalanceStatisticsDto>();
decimal cumulativeBalance = 0;
foreach (var item in sortedStats)
{
var dailyBalance = item.Value.income - item.Value.expense;
cumulativeBalance += dailyBalance;
result.Add(new BalanceStatisticsDto(DateTime.Parse(item.Key).Day, cumulativeBalance));
}
return result;
}
public async Task<List<DailyStatisticsDto>> GetDailyStatisticsAsync(int year, int month)
{
var savingClassify = await configService.GetConfigByKeyAsync<string>("SavingsCategories");
var statistics = await statisticsService.GetDailyStatisticsAsync(year, month, savingClassify);
return statistics.Select(s => new DailyStatisticsDto(
DateTime.Parse(s.Key).Day, // 从完整日期字符串 "yyyy-MM-dd" 中提取 day
s.Value.count,
s.Value.expense,
s.Value.income,
s.Value.saving
)).ToList();
}
public async Task<List<DailyStatisticsDto>> GetWeeklyStatisticsAsync(DateTime startDate, DateTime endDate)
{
var savingClassify = await configService.GetConfigByKeyAsync<string>("SavingsCategories");
var statistics = await statisticsService.GetDailyStatisticsByRangeAsync(startDate, endDate, savingClassify);
return statistics.Select(s => new DailyStatisticsDto(
DateTime.Parse(s.Key).Day, // 从完整日期字符串 "yyyy-MM-dd" 中提取 day
s.Value.count,
s.Value.expense,
s.Value.income,
s.Value.saving
)).ToList();
}
public async Task<MonthlyStatistics> GetRangeStatisticsAsync(DateTime startDate, DateTime endDate)
{
var records = await statisticsService.GetDailyStatisticsByRangeAsync(startDate, endDate, null);
var totalExpense = records.Sum(r => r.Value.expense);
var totalIncome = records.Sum(r => r.Value.income);
var totalCount = records.Sum(r => r.Value.count);
var expenseCount = records.Count(r => r.Value.expense > 0);
var incomeCount = records.Count(r => r.Value.income > 0);
return new MonthlyStatistics
{
Year = startDate.Year,
Month = startDate.Month,
TotalExpense = totalExpense,
TotalIncome = totalIncome,
Balance = totalIncome - totalExpense,
ExpenseCount = expenseCount,
IncomeCount = incomeCount,
TotalCount = totalCount
};
}
public async Task<MonthlyStatistics> GetMonthlyStatisticsAsync(int year, int month)
{
return await statisticsService.GetMonthlyStatisticsAsync(year, month);
}
public async Task<List<CategoryStatistics>> GetCategoryStatisticsAsync(int year, int month, TransactionType type)
{
return await statisticsService.GetCategoryStatisticsAsync(year, month, type);
}
public async Task<List<CategoryStatistics>> GetCategoryStatisticsByDateRangeAsync(string startDate, string endDate, TransactionType type)
{
var start = DateTime.Parse(startDate);
var end = DateTime.Parse(endDate);
return await statisticsService.GetCategoryStatisticsByDateRangeAsync(start, end, type);
}
public async Task<List<TrendStatistics>> GetTrendStatisticsAsync(int startYear, int startMonth, int monthCount)
{
return await statisticsService.GetTrendStatisticsAsync(startYear, startMonth, monthCount);
}
public async Task<(List<ReasonGroupDto> list, int total)> GetReasonGroupsAsync(int pageIndex, int pageSize)
{
return await statisticsService.GetReasonGroupsAsync(pageIndex, pageSize);
}
}