8.3 KiB
Bug修复交接文档
日期: 2026-02-14
变更名称: fix-budget-and-ui-bugs
OpenSpec路径: openspec/changes/fix-budget-and-ui-bugs/
状态: 已创建变更目录,待创建artifacts
发现的Bug汇总 (共6个)
Bug #1: 统计页面路由无法跳转
影响: 底部导航栏
问题: 点击底部导航的"统计"标签后无法正常跳转
原因: 导航栏配置的路由可能不正确,实际统计页面路由是 /statistics-v2
位置: Web/src/router/index.js 和底部导航配置
Bug #2: 删除账单功能无响应
影响: 日历页面账单详情弹窗
问题: 点击账单详情弹窗中的"删除"按钮后,弹窗不关闭,账单未被删除
原因: 删除按钮的点击事件可能未正确绑定,或需要二次确认对话框但未弹出
位置: 日历页面的账单详情组件
Bug #3: Console警告 van-datetime-picker组件未找到
影响: 全局
问题: 控制台显示 Failed to resolve component: van-datetime-picker
原因: Vant组件未正确导入或注册
位置: 全局组件注册
Bug #4: 预算明细弹窗显示"暂无数据" ⭐⭐⭐
影响: 预算页面(支出/收入标签)
问题: 点击"使用情况"或"完成情况"旁的感叹号图标,弹出的"预算额度/实际详情"对话框显示"暂无数据"
根本原因:
-
✅ 后端Service层正确生成了
Description字段BudgetStatsService.cs第280行和495行调用GenerateMonthlyDescription和GenerateYearlyDescription- 生成HTML格式的详细描述(包含表格和计算公式)
-
✅ 后端DTO层有
Description字段Service/Budget/BudgetService.cs第525行:public string Description { get; set; } = string.Empty;
-
❌ Application层丢失数据
Application/BudgetApplication.cs第80-96行在映射时没有包含Description字段
-
❌ API响应DTO缺少字段
Application/Dto/BudgetDto.cs第64-70行的BudgetStatsDetail类没有定义Description属性
前端显示逻辑:
Web/src/components/Budget/BudgetChartAnalysis.vue第199-203行- 弹窗内容:
v-html="activeDescTab === 'month' ? (overallStats.month?.description || '<p>暂无数据</p>') : ..."
修复方案:
- 在
BudgetStatsDetail(Application/Dto/BudgetDto.cs:64-70) 添加Description字段 - 在
BudgetApplication.GetCategoryStatsAsync(Application/BudgetApplication.cs:80-96) 映射Description字段
Bug #5: 燃尽图显示为直线 ⭐⭐⭐
影响: 预算页面(支出/收入/计划)的月度和年度燃尽图
问题: 实际燃尽/积累线显示为直线,无法看到真实的支出/收入趋势波动
根本原因:
-
✅ 后端Service层正确计算并填充了
Trend字段BudgetStatsService.cs第231行:result.Trend.Add(adjustedAccumulated);- Trend是每日/每月累计金额的数组
-
✅ 后端DTO层有
Trend字段Service/Budget/BudgetService.cs第520行:public List<decimal?> Trend { get; set; } = [];
-
❌ Application层丢失数据
Application/BudgetApplication.cs第80-96行在映射时没有包含Trend字段
-
❌ API响应DTO缺少字段
Application/Dto/BudgetDto.cs第64-70行的BudgetStatsDetail类没有定义Trend属性
前端Fallback行为:
Web/src/components/Budget/BudgetChartAnalysis.vue第591行:const trend = props.overallStats.month.trend || []- 当
trend.length === 0时(第603行和第629行),使用线性估算:- 支出:
actualRemaining = totalBudget - (currentExpense * i / currentDay)(第616行) - 收入:
actualAccumulated = Math.min(totalBudget, currentExpense * i / currentDay)(第638行)
- 支出:
- 导致"实际燃尽/积累"线是一条直线
修复方案:
- 在
BudgetStatsDetail(Application/Dto/BudgetDto.cs:64-70) 添加Trend字段 - 在
BudgetApplication.GetCategoryStatsAsync(Application/BudgetApplication.cs:80-96) 映射Trend字段
Bug #6: 预算卡片金额与关联账单列表金额不一致 ⭐
影响: 预算页面,点击预算卡片的"查询关联账单"按钮
问题: 显示的关联账单列表中的金额总和,与预算卡片上显示的"实际"金额不一致
可能原因:
-
日期范围不一致:
- 预算卡片
current: 使用GetPeriodRange计算(BudgetService.cs:410-432)- 月度: 当月1号 00:00:00 到当月最后一天 23:59:59
- 年度: 当年1月1号到12月31日 23:59:59
- 关联账单查询: 使用
budget.periodStart和budget.periodEnd(BudgetCard.vue:470-471) - 如果两者不一致,会导致查询范围不同
- 预算卡片
-
硬性预算的虚拟消耗:
- 标记为📌的硬性预算(生活费、车贷等),如果没有实际交易记录,后端按天数比例虚拟累加金额(BudgetService.cs:376-405)
- 前端查询账单列表只能查到实际交易记录,查不到虚拟消耗
- 导致: 卡片显示金额 > 账单列表金额总和
需要验证:
BudgetResult中PeriodStart和PeriodEnd的赋值逻辑- 硬性预算虚拟消耗的处理
- 前端是否需要显示虚拟消耗提示
修复思路:
- 选项1: 确保
periodStart/periodEnd与GetPeriodRange一致 - 选项2: 在账单列表中显示虚拟消耗的说明/提示
- 选项3: 提供切换按钮,允许显示/隐藏虚拟消耗
共性问题分析
Bug #4 和 #5 的共同根源:
Application/Dto/BudgetDto.cs中BudgetStatsDetail类(第64-70行)定义不完整- 缺少字段:
Description(string) - 用于明细弹窗Trend(List<decimal?>) - 用于燃尽图
当前定义:
public record BudgetStatsDetail
{
public decimal Limit { get; init; }
public decimal Current { get; init; }
public decimal Remaining { get; init; }
public decimal UsagePercentage { get; init; }
}
需要补充:
public record BudgetStatsDetail
{
public decimal Limit { get; init; }
public decimal Current { get; init; }
public decimal Remaining { get; init; }
public decimal UsagePercentage { get; init; }
public List<decimal?> Trend { get; init; } = new(); // ⬅️ 新增
public string Description { get; init; } = string.Empty; // ⬅️ 新增
}
关键文件清单
后端文件
Service/Budget/BudgetStatsService.cs- 统计计算逻辑,生成Description和TrendService/Budget/BudgetService.cs- BudgetStatsDto定义(含Description和Trend)Application/BudgetApplication.cs- DTO映射逻辑(需要修改)Application/Dto/BudgetDto.cs- API响应DTO定义(需要修改)WebApi/Controllers/BudgetController.cs- API控制器
前端文件
Web/src/components/Budget/BudgetChartAnalysis.vue- 图表和明细弹窗组件Web/src/components/Budget/BudgetCard.vue- 预算卡片组件,包含账单查询逻辑Web/src/router/index.js- 路由配置(Bug #1)
下一步行动
立即执行
cd D:/codes/others/EmailBill
openspec status --change "fix-budget-and-ui-bugs"
OpenSpec工作流
- 使用
/opsx-continue或/opsx-ff继续创建artifacts - 变更已创建在:
openspec/changes/fix-budget-and-ui-bugs/ - 需要创建的artifacts (按schema要求):
- Problem Statement
- Tasks
- 其他必要的artifacts
优先级建议
- 高优先级 (P0): Bug #4, #5 - 影响核心功能,修复简单(只需补充DTO字段)
- 中优先级 (P1): Bug #1, #2 - 影响用户体验
- 低优先级 (P2): Bug #3, #6 - 影响较小或需要更多分析
测试验证点
修复后需要验证:
- ✅ 预算明细弹窗显示完整的HTML表格和计算公式
- ✅ 燃尽图显示真实的波动曲线而非直线
- ✅ 底部导航可以正常跳转到统计页面
- ✅ 删除账单功能正常工作
- ✅ 控制台无van-datetime-picker警告
- ✅ 预算卡片金额与账单列表金额一致(或有明确说明差异原因)
联系信息
- 前端服务: http://localhost:5173
- 后端服务: http://localhost:5000
- 浏览器已打开,测试环境就绪
生成时间: 2026-02-14 10:30
Token使用: 96418/200000 (48%)
下一个Agent: 请继续 OpenSpec 工作流创建 artifacts 并实施修复