219 lines
8.3 KiB
Markdown
219 lines
8.3 KiB
Markdown
|
|
# 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: 预算明细弹窗显示"暂无数据" ⭐⭐⭐
|
|||
|
|
**影响**: 预算页面(支出/收入标签)
|
|||
|
|
**问题**: 点击"使用情况"或"完成情况"旁的感叹号图标,弹出的"预算额度/实际详情"对话框显示"暂无数据"
|
|||
|
|
|
|||
|
|
**根本原因**:
|
|||
|
|
1. ✅ **后端Service层**正确生成了 `Description` 字段
|
|||
|
|
- `BudgetStatsService.cs` 第280行和495行调用 `GenerateMonthlyDescription` 和 `GenerateYearlyDescription`
|
|||
|
|
- 生成HTML格式的详细描述(包含表格和计算公式)
|
|||
|
|
|
|||
|
|
2. ✅ **后端DTO层**有 `Description` 字段
|
|||
|
|
- `Service/Budget/BudgetService.cs` 第525行:`public string Description { get; set; } = string.Empty;`
|
|||
|
|
|
|||
|
|
3. ❌ **Application层丢失数据**
|
|||
|
|
- `Application/BudgetApplication.cs` 第80-96行在映射时**没有包含 `Description` 字段**
|
|||
|
|
|
|||
|
|
4. ❌ **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>') : ..."`
|
|||
|
|
|
|||
|
|
**修复方案**:
|
|||
|
|
1. 在 `BudgetStatsDetail` (Application/Dto/BudgetDto.cs:64-70) 添加 `Description` 字段
|
|||
|
|
2. 在 `BudgetApplication.GetCategoryStatsAsync` (Application/BudgetApplication.cs:80-96) 映射 `Description` 字段
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Bug #5: 燃尽图显示为直线 ⭐⭐⭐
|
|||
|
|
**影响**: 预算页面(支出/收入/计划)的月度和年度燃尽图
|
|||
|
|
**问题**: 实际燃尽/积累线显示为直线,无法看到真实的支出/收入趋势波动
|
|||
|
|
|
|||
|
|
**根本原因**:
|
|||
|
|
1. ✅ **后端Service层**正确计算并填充了 `Trend` 字段
|
|||
|
|
- `BudgetStatsService.cs` 第231行: `result.Trend.Add(adjustedAccumulated);`
|
|||
|
|
- Trend是每日/每月累计金额的数组
|
|||
|
|
|
|||
|
|
2. ✅ **后端DTO层**有 `Trend` 字段
|
|||
|
|
- `Service/Budget/BudgetService.cs` 第520行:`public List<decimal?> Trend { get; set; } = [];`
|
|||
|
|
|
|||
|
|
3. ❌ **Application层丢失数据**
|
|||
|
|
- `Application/BudgetApplication.cs` 第80-96行在映射时**没有包含 `Trend` 字段**
|
|||
|
|
|
|||
|
|
4. ❌ **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行)
|
|||
|
|
- 导致"实际燃尽/积累"线是一条**直线**
|
|||
|
|
|
|||
|
|
**修复方案**:
|
|||
|
|
1. 在 `BudgetStatsDetail` (Application/Dto/BudgetDto.cs:64-70) 添加 `Trend` 字段
|
|||
|
|
2. 在 `BudgetApplication.GetCategoryStatsAsync` (Application/BudgetApplication.cs:80-96) 映射 `Trend` 字段
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Bug #6: 预算卡片金额与关联账单列表金额不一致 ⭐
|
|||
|
|
**影响**: 预算页面,点击预算卡片的"查询关联账单"按钮
|
|||
|
|
**问题**: 显示的关联账单列表中的金额总和,与预算卡片上显示的"实际"金额不一致
|
|||
|
|
|
|||
|
|
**可能原因**:
|
|||
|
|
1. **日期范围不一致**:
|
|||
|
|
- 预算卡片 `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)
|
|||
|
|
- **如果两者不一致,会导致查询范围不同**
|
|||
|
|
|
|||
|
|
2. **硬性预算的虚拟消耗**:
|
|||
|
|
- 标记为📌的硬性预算(生活费、车贷等),如果没有实际交易记录,后端按天数比例虚拟累加金额(BudgetService.cs:376-405)
|
|||
|
|
- 前端查询账单列表只能查到实际交易记录,查不到虚拟消耗
|
|||
|
|
- **导致: 卡片显示金额 > 账单列表金额总和**
|
|||
|
|
|
|||
|
|
**需要验证**:
|
|||
|
|
1. `BudgetResult` 中 `PeriodStart` 和 `PeriodEnd` 的赋值逻辑
|
|||
|
|
2. 硬性预算虚拟消耗的处理
|
|||
|
|
3. 前端是否需要显示虚拟消耗提示
|
|||
|
|
|
|||
|
|
**修复思路**:
|
|||
|
|
- 选项1: 确保 `periodStart/periodEnd` 与 `GetPeriodRange` 一致
|
|||
|
|
- 选项2: 在账单列表中显示虚拟消耗的说明/提示
|
|||
|
|
- 选项3: 提供切换按钮,允许显示/隐藏虚拟消耗
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 共性问题分析
|
|||
|
|
|
|||
|
|
**Bug #4 和 #5 的共同根源**:
|
|||
|
|
- `Application/Dto/BudgetDto.cs` 中 `BudgetStatsDetail` 类(第64-70行)定义不完整
|
|||
|
|
- 缺少字段:
|
|||
|
|
- `Description` (string) - 用于明细弹窗
|
|||
|
|
- `Trend` (List<decimal?>) - 用于燃尽图
|
|||
|
|
|
|||
|
|
**当前定义**:
|
|||
|
|
```csharp
|
|||
|
|
public record BudgetStatsDetail
|
|||
|
|
{
|
|||
|
|
public decimal Limit { get; init; }
|
|||
|
|
public decimal Current { get; init; }
|
|||
|
|
public decimal Remaining { get; init; }
|
|||
|
|
public decimal UsagePercentage { get; init; }
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**需要补充**:
|
|||
|
|
```csharp
|
|||
|
|
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和Trend
|
|||
|
|
- `Service/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)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 下一步行动
|
|||
|
|
|
|||
|
|
### 立即执行
|
|||
|
|
```bash
|
|||
|
|
cd D:/codes/others/EmailBill
|
|||
|
|
openspec status --change "fix-budget-and-ui-bugs"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### OpenSpec工作流
|
|||
|
|
1. 使用 `/opsx-continue` 或 `/opsx-ff` 继续创建artifacts
|
|||
|
|
2. 变更已创建在: `openspec/changes/fix-budget-and-ui-bugs/`
|
|||
|
|
3. 需要创建的artifacts (按schema要求):
|
|||
|
|
- Problem Statement
|
|||
|
|
- Tasks
|
|||
|
|
- 其他必要的artifacts
|
|||
|
|
|
|||
|
|
### 优先级建议
|
|||
|
|
1. **高优先级 (P0)**: Bug #4, #5 - 影响核心功能,修复简单(只需补充DTO字段)
|
|||
|
|
2. **中优先级 (P1)**: Bug #1, #2 - 影响用户体验
|
|||
|
|
3. **低优先级 (P2)**: Bug #3, #6 - 影响较小或需要更多分析
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 测试验证点
|
|||
|
|
|
|||
|
|
修复后需要验证:
|
|||
|
|
1. ✅ 预算明细弹窗显示完整的HTML表格和计算公式
|
|||
|
|
2. ✅ 燃尽图显示真实的波动曲线而非直线
|
|||
|
|
3. ✅ 底部导航可以正常跳转到统计页面
|
|||
|
|
4. ✅ 删除账单功能正常工作
|
|||
|
|
5. ✅ 控制台无van-datetime-picker警告
|
|||
|
|
6. ✅ 预算卡片金额与账单列表金额一致(或有明确说明差异原因)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 联系信息
|
|||
|
|
- 前端服务: http://localhost:5173
|
|||
|
|
- 后端服务: http://localhost:5000
|
|||
|
|
- 浏览器已打开,测试环境就绪
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**生成时间**: 2026-02-14 10:30
|
|||
|
|
**Token使用**: 96418/200000 (48%)
|
|||
|
|
**下一个Agent**: 请继续 OpenSpec 工作流创建 artifacts 并实施修复
|