- 添加 BudgetItemCalculator 辅助类,实现明细项计算规则 - 收入:实际>0取实际,否则取预算 - 支出:取MAX(预算, 实际) - 硬性支出未发生:按天数折算 - 归档数据:直接使用实际值 - 实现月度和年度存款核心公式 - 月度:收入预算 + 本月年度收入 - 支出预算 - 本月年度支出 - 年度:归档已实收 + 未来收入预算 - 归档已实支 - 未来支出预算 - 定义存款明细数据结构 - SavingsDetail: 包含收入/支出明细列表和汇总 - BudgetDetailItem: 预算明细项(含计算用金额、计算说明等) - SavingsCalculationSummary: 计算汇总信息 - 新增单元测试 - BudgetItemCalculatorTest: 11个测试覆盖所有计算规则 - BudgetSavingsCalculationTest: 6个测试验证核心公式 测试结果:所有测试通过 (366 passed, 0 failed)
6.9 KiB
6.9 KiB
Tasks: 存款明细计算优化实施清单
1. 数据结构定义
- 1.1 在
Application/Dto/BudgetDto.cs中定义SavingsDetailrecord 类型 - 1.2 在
Application/Dto/BudgetDto.cs中定义BudgetDetailItemrecord 类型 - 1.3 在
Application/Dto/BudgetDto.cs中定义SavingsCalculationSummaryrecord 类型 - 1.4 在
BudgetResult中添加Details属性(类型为SavingsDetail?)
2. 核心计算辅助类 - TDD 红灯阶段
- 2.1 创建
WebApi.Test/Budget/BudgetItemCalculatorTest.cs测试文件 - 2.2 编写测试:收入项实际已发生(actual > 0)应返回实际值
- 2.3 编写测试:收入项实际未发生(actual = 0)应返回预算值
- 2.4 编写测试:支出项普通情况应返回 MAX(预算, 实际)
- 2.5 编写测试:支出项未超预算应返回预算值
- 2.6 编写测试:支出项超预算应返回实际值
- 2.7 编写测试:支出项硬性且实际为0(月度)应按天数折算
- 2.8 编写测试:支出项硬性且实际为0(年度)应按天数折算
- 2.9 编写测试:支出项硬性且实际>0应返回MAX值
- 2.10 编写测试:归档数据应直接返回实际值
- 2.11 编写测试:闰年2月按天折算边界情况
- 2.12 编写测试:平年2月按天折算边界情况
- 2.13 运行所有测试,确认红灯(测试失败)
3. 核心计算辅助类 - TDD 绿灯阶段
- 3.1 创建
Service/Budget/BudgetItemCalculator.cs静态类 - 3.2 实现
CalculateEffectiveAmount方法(包含所有计算规则) - 3.3 实现
CalculateMandatoryAmount私有方法(硬性消费按天折算) - 3.4 实现
GenerateCalculationNote方法(生成计算说明) - 3.5 运行所有测试,确认绿灯(测试通过)
4. 月度存款核心公式 - TDD 红灯阶段
- 4.1 创建
WebApi.Test/Budget/BudgetSavingsCalculationTest.cs测试文件 - 4.2 编写测试:月度计划存款公式 - 纯月度预算场景
- 4.3 编写测试:月度计划存款公式 - 月度预算 + 本月发生的年度预算
- 4.4 编写测试:月度计划存款公式 - 年度预算未在本月发生应不计入
- 4.5 运行测试,确认红灯
5. 月度存款核心公式 - TDD 绿灯阶段
- 5.1 在
BudgetSavingsService中添加CalculateMonthlyPlannedSavings私有方法 - 5.2 实现月度计划存款公式:收入预算 + 本月年度收入 - 支出预算 - 本月年度支出
- 5.3 运行测试,确认绿灯
6. 年度存款核心公式 - TDD 红灯阶段
- 6.1 编写测试:年度计划存款公式 - 年初无归档数据场景
- 6.2 编写测试:年度计划存款公式 - 年中有归档数据场景
- 6.3 编写测试:年度计划存款公式 - 归档数据包含年度预算
- 6.4 运行测试,确认红灯
7. 年度存款核心公式 - TDD 绿灯阶段
- 7.1 在
BudgetSavingsService中添加CalculateYearlyPlannedSavings私有方法 - 7.2 实现年度计划存款公式:归档已实收 + 未来收入预算 - 归档已实支 - 未来支出预算
- 7.3 运行测试,确认绿灯
8. 重构 GetForMonthAsync - TDD 红灯阶段
- 8.1 在
WebApi.Test/Budget/BudgetSavingsTest.cs中编写测试:月度查询应返回 Details 字段 - 8.2 编写测试:月度明细应包含所有月度预算项
- 8.3 编写测试:月度明细应包含本月发生的年度预算项
- 8.4 编写测试:月度明细中每项应包含计算用金额和计算说明
- 8.5 编写测试:超支项目应标记 IsOverBudget = true
- 8.6 编写测试:不记额预算应排除在汇总之外
- 8.7 运行测试,确认红灯
9. 重构 GetForMonthAsync - TDD 绿灯阶段
- 9.1 重构
GetForMonthAsync方法,使用CalculateMonthlyPlannedSavings - 9.2 添加明细数据收集逻辑(创建
BudgetDetailItem列表) - 9.3 为每个预算项调用
BudgetItemCalculator.CalculateEffectiveAmount - 9.4 生成
SavingsDetail对象并填充到BudgetResult.Details - 9.5 生成
SavingsCalculationSummary汇总信息 - 9.6 保留原有的 HTML
Description生成逻辑(向后兼容) - 9.7 运行测试,确认绿灯
10. 重构 GetForYearAsync - TDD 红灯阶段
- 10.1 编写测试:年度查询应返回 Details 字段
- 10.2 编写测试:年度明细应包含归档月份标注(IsArchived = true)
- 10.3 编写测试:年度明细应包含 ArchivedMonths 字段
- 10.4 编写测试:归档数据应使用归档的实际值
- 10.5 编写测试:未来月份预算应正确折算
- 10.6 编写测试:年度预算项不应重复计算
- 10.7 运行测试,确认红灯
11. 重构 GetForYearAsync - TDD 绿灯阶段
- 11.1 重构
GetForYearAsync方法,使用CalculateYearlyPlannedSavings - 11.2 添加归档数据读取和明细项创建逻辑
- 11.3 为归档数据标注
IsArchived = true和ArchivedMonths - 11.4 添加未来月份预算的明细项创建逻辑
- 11.5 生成
SavingsDetail对象并填充到BudgetResult.Details - 11.6 保留原有的 HTML
Description生成逻辑(向后兼容) - 11.7 运行测试,确认绿灯
12. 边界情况测试
- 12.1 编写测试:闰年年度硬性支出按天折算
- 12.2 编写测试:平年年度硬性支出按天折算
- 12.3 编写测试:月初(1号)硬性支出折算
- 12.4 编写测试:月末(28/29/30/31号)硬性支出折算
- 12.5 编写测试:不记额预算的处理
- 12.6 编写测试:无预算项时的空列表处理
- 12.7 编写测试:所有预算项实际为0的情况
- 12.8 运行所有边界测试,确认通过
13. 集成测试
- 13.1 编写完整场景集成测试:月度查询包含月度+年度混合
- 13.2 编写完整场景集成测试:年度查询包含归档+未来混合
- 13.3 编写集成测试:验证 HTML Description 和 Details 数据一致性
- 13.4 编写集成测试:验证与 BudgetArchiveRepository 的集成
- 13.5 编写集成测试:验证与 TransactionStatisticsService 的集成
- 13.6 运行所有集成测试,确认通过
14. 代码审查与重构
- 14.1 审查所有新增代码,确保符合项目编码规范
- 14.2 检查中文注释是否完整清晰
- 14.3 重构重复代码,提取共用方法
- 14.4 优化变量命名,确保语义清晰
- 14.5 运行所有测试,确保重构后测试仍然通过
15. 文档与验收
- 15.1 更新
BudgetSavingsService相关方法的 XML 文档注释 - 15.2 添加
BudgetItemCalculator的使用示例注释 - 15.3 运行完整测试套件:
dotnet test WebApi.Test/WebApi.Test.csproj - 15.4 验证所有测试通过(0 failed)
- 15.5 手动验证:通过 API 调用验证返回数据格式正确
- 15.6 确认向后兼容:旧版前端仍可正常使用 Description 字段