- 添加 BudgetItemCalculator 辅助类,实现明细项计算规则 - 收入:实际>0取实际,否则取预算 - 支出:取MAX(预算, 实际) - 硬性支出未发生:按天数折算 - 归档数据:直接使用实际值 - 实现月度和年度存款核心公式 - 月度:收入预算 + 本月年度收入 - 支出预算 - 本月年度支出 - 年度:归档已实收 + 未来收入预算 - 归档已实支 - 未来支出预算 - 定义存款明细数据结构 - SavingsDetail: 包含收入/支出明细列表和汇总 - BudgetDetailItem: 预算明细项(含计算用金额、计算说明等) - SavingsCalculationSummary: 计算汇总信息 - 新增单元测试 - BudgetItemCalculatorTest: 11个测试覆盖所有计算规则 - BudgetSavingsCalculationTest: 6个测试验证核心公式 测试结果:所有测试通过 (366 passed, 0 failed)
2.8 KiB
2.8 KiB
MODIFIED Requirements
Requirement: Display income and expense budget in savings detail popup
The savings detail popup SHALL display the associated income budget and expense budget information for the selected savings plan, including both budget limits and current amounts.
Scenario: User opens savings detail popup with matched budgets
- WHEN user clicks the detail button on a savings plan card
- AND there exist income and expense budgets for the same period and type
- THEN the popup SHALL display the income budget limit and current amount
- AND the popup SHALL display the expense budget limit and current amount
- AND the popup SHALL display the savings formula (Income Limit - Expense Limit = Planned Savings)
- AND the popup SHALL display the savings result (Planned Savings, Actual Savings, Remaining)
Scenario: User opens savings detail popup without matched budgets
- WHEN user clicks the detail button on a savings plan card
- AND there are no income or expense budgets for the same period and type
- THEN the popup SHALL display 0 for income budget limit and current amount
- AND the popup SHALL display 0 for expense budget limit and current amount
- AND the popup SHALL still display the savings formula and result with these values
Requirement: Pass budget data to savings component
The parent component (Index.vue) SHALL pass income budgets and expense budgets to the SavingsBudgetContent component to enable detail popup display.
Scenario: Budget data is loaded successfully
- WHEN the budget data is loaded from the API
- THEN the income budgets SHALL be passed to SavingsBudgetContent via props
- AND the expense budgets SHALL be passed to SavingsBudgetContent via props
- AND the savings budgets SHALL be passed to SavingsBudgetContent via props (existing behavior)
Requirement: Match income and expense budgets to savings plan
The SavingsBudgetContent component SHALL match income and expense budgets to the current savings plan based on periodStart and type fields.
Scenario: Match budgets with same period and type
- WHEN displaying savings plan details
- AND the component searches for matching budgets
- THEN the component SHALL find income budgets where periodStart and type match the savings plan
- AND the component SHALL find expense budgets where periodStart and type match the savings plan
- AND if multiple matches exist, the component SHALL use the first match
Scenario: No matching budgets found
- WHEN displaying savings plan details
- AND no income budget matches the savings plan's periodStart and type
- OR no expense budget matches the savings plan's periodStart and type
- THEN the component SHALL use 0 as the default value for unmatched budget fields
- AND the popup SHALL still render without errors