1
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Waiting to run
Docker Build & Deploy / Deploy to Production (push) Has been cancelled
Docker Build & Deploy / Cleanup Dangling Images (push) Has been cancelled
Docker Build & Deploy / WeChat Notification (push) Has been cancelled

This commit is contained in:
SunCheng
2026-02-18 21:16:45 +08:00
parent 77c9b47246
commit c49f66757e
116 changed files with 6909 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
## REMOVED Requirements
### Requirement: Get Uncovered Categories
**Reason**: 该接口仅被 V1 预算页面使用,用于展示"未设置预算的分类"。V2 预算页面不包含此功能。
**Migration**: 如需在 V2 中实现类似功能,应重新设计并创建新接口。当前无直接迁移路径。
**原有功能**:
- **接口**: `GET /api/Budget/GetUncoveredCategories`
- **Controller**: `BudgetController.GetUncoveredCategoriesAsync`
- **参数**: `category` (enum: Expense/Income/Saving), `date` (DateTime)
- **返回**: `List<string>` (未设置预算的分类名称列表)
- **业务逻辑**:
1. 查询指定月份的所有交易记录,提取所有出现的分类
2. 查询指定月份已设置预算的分类
3. 计算差集,返回"有交易但未设置预算"的分类列表
**被以下代码调用**:
- `Web/src/views/BudgetView.vue` 中的 `fetchUncoveredCategories` 方法
- `Web/src/api/budget.js` 中的 `getUncoveredCategories` 函数
---
### Requirement: Get Archive Summary
**Reason**: 该接口仅被 V1 预算页面使用,用于展示"历史预算归档总结"。V2 预算页面不包含此功能。
**Migration**: 如需在 V2 中实现类似功能,应重新设计并创建新接口。当前无直接迁移路径。
**原有功能**:
- **接口**: `GET /api/Budget/GetArchiveSummary`
- **Controller**: `BudgetController.GetArchiveSummaryAsync`
- **参数**: `date` (DateTime, 用于指定查询的年月)
- **返回**: `ArchiveSummaryDto` (包含归档总结数据)
- **业务逻辑**:
1. 查询 `BudgetArchive` 表中指定月份的归档记录
2. 汇总支出、收入、存款的预算执行情况
3. 返回总结数据(如预算达成率、超支分类等)
**被以下代码调用**:
- `Web/src/views/BudgetView.vue` 中的 `showArchiveSummary` 方法
- `Web/src/api/budget.js` 中的 `getArchiveSummary` 函数
---
## Context
本规范定义了 EmailBill 后端 `BudgetController` 中两个 V1 专用接口的移除操作。
### 接口背景
这两个接口是 V1 预算页面的特色功能:
1. **未覆盖分类提示**: 帮助用户发现"有交易但未设置预算"的分类,提醒用户完善预算设置
2. **归档总结**: 展示历史月份的预算执行总结,帮助用户回顾过去的财务状况
### V2 设计变更
V2 预算页面重新设计了用户体验,移除了上述两个功能:
- **未覆盖分类**: V2 采用"按需创建预算"模式,不主动提示未覆盖分类
- **归档总结**: V2 使用实时统计替代归档总结,用户可随时查看任意月份的预算执行情况
### 技术依赖
这两个接口依赖以下 Service 和 Repository
- `BudgetService.GetUncoveredCategoriesAsync`
- `BudgetService.GetArchiveSummaryAsync`
- `BudgetRepository`
- `BudgetArchiveRepository`
- `TransactionRecordRepository`
移除接口后,相关 Service 方法也将被移除(见 `budget-service` 规范)。
---
## Validation
### 验证标准
1. **代码搜索验证**:
- 全局搜索 `GetUncoveredCategories`,确认仅在以下位置出现:
- `BudgetController.GetUncoveredCategoriesAsync` (待删除)
- `BudgetApplication.GetUncoveredCategoriesAsync` (待删除)
- `BudgetService.GetUncoveredCategoriesAsync` (待删除)
- `BudgetView.vue` (已删除)
- `budget.js` (已清理)
- 全局搜索 `GetArchiveSummary`,确认仅在 V1 相关代码中出现
2. **编译验证**:
- 删除 `BudgetController` 中的两个方法后,后端项目编译通过
- 删除 `BudgetApplication``BudgetService` 中的对应方法后,编译通过
3. **API 文档验证**:
- Swagger/Scalar 文档中不再显示以下端点:
- `/api/Budget/GetUncoveredCategories`
- `/api/Budget/GetArchiveSummary`
4. **运行时验证**:
- 前端调用上述端点返回 404
- V2 预算页面 (`/budget-v2`) 正常加载和操作,不受影响
---
## Dependencies
移除这两个接口的前置条件:
1. `BudgetView.vue` (V1 预算页面) 已删除
2. `Web/src/api/budget.js` 中的 `getUncoveredCategories``getArchiveSummary` 方法已清理
3. V2 预算页面已验证不依赖这两个接口
移除后连带删除:
- `BudgetApplication.GetUncoveredCategoriesAsync`
- `BudgetApplication.GetArchiveSummaryAsync`
- `BudgetService.GetUncoveredCategoriesAsync`
- `BudgetService.GetArchiveSummaryAsync`
移除后不影响:
- 其他预算相关接口 (`GetList`, `GetCategoryStats`, `Create`, `Update`, `Delete` 等)
- `BudgetRepository``BudgetArchiveRepository` 的查询逻辑 (仍被其他接口使用)
- V2 预算页面的任何功能
---
## Notes
### 功能对比表
| 功能 | V1 实现 | V2 实现 |
|------|---------|---------|
| **未覆盖分类提示** | 专用接口 `GetUncoveredCategories` | 无(按需创建预算) |
| **归档总结** | 专用接口 `GetArchiveSummary` | 实时统计 `GetCategoryStats` |
| **预算列表** | `GetList` | `GetList` (共用) |
| **分类统计** | `GetCategoryStats` | `GetCategoryStats` (共用) |
### 潜在影响
如果未来需要在 V2 中恢复"未覆盖分类"或"归档总结"功能:
1. **不能直接恢复删除的代码**,因为业务逻辑可能已过时
2. **应重新设计接口**,考虑 V2 的数据模型和用户体验
3. **建议先调研用户需求**,确认是否真的需要这些功能

View File

@@ -0,0 +1,77 @@
## REMOVED Requirements
### Requirement: Calendar View Route
**Reason**: V1 日历页面已由 V2 版本完全替代V1 路由不再需要
**Migration**: 用户应访问 `/calendar-v2` 路由,使用新版日历功能
---
### Requirement: Budget View Route
**Reason**: V1 预算页面已由 V2 版本完全替代V1 路由不再需要
**Migration**: 用户应访问 `/budget-v2` 路由,使用新版预算管理功能
---
### Requirement: Statistics V1 Default Route
**Reason**: V1 统计页面已由 V2 版本完全替代V1 默认路由不再需要
**Migration**: 系统默认路由应指向 `/statistics-v2`,用户将自动使用新版统计功能
---
### Requirement: V1/V2 Version Toggle Logic
**Reason**: V1 版本完全下线后,版本切换逻辑不再需要
**Migration**: 移除 `useVersionStore` 中的版本切换代码,简化路由守卫逻辑。所有用户默认使用 V2 版本。
---
## Context
本规范定义了 EmailBill 前端路由系统中 V1 相关路由的移除操作。随着 V2 版本的稳定上线V1 的日历、预算、统计三个核心模块的路由定义已成为遗留代码。
### 受影响的路由
- `/calendar` → CalendarView.vue (V1 日历视图)
- `/budget` → BudgetView.vue (V1 预算管理)
- `/` → statisticsV1/Index.vue (V1 统计页面,默认首页)
### 现有版本控制机制
- `useVersionStore` 提供 `isV2()` 方法判断用户偏好
- 路由守卫根据版本偏好自动跳转到对应的 V1 或 V2 路由
- V2 路由命名规则: 原路由名 + `-v2` 后缀
### 移除后的预期行为
- 访问 `/calendar``/budget``/` 将返回 404 或重定向到 V2 版本
- `useVersionStore` 中的版本切换逻辑被简化或移除
- 路由守卫不再需要判断 V1/V2 版本
---
## Validation
### 验证标准
1. **路由配置文件** (`Web/src/router/index.js`):
- 不包含 `/calendar`, `/budget`, `/` 的 V1 路由定义
- V2 路由 (`/calendar-v2`, `/budget-v2`, `/statistics-v2`) 正常工作
2. **版本控制逻辑** (`Web/src/stores/version.js` 或类似文件):
- 移除或简化 `isV2()` 相关的版本切换代码
- 确保所有路由默认使用 V2 版本
3. **手动测试验证**:
- 直接访问 `/calendar` 不会加载 V1 页面
- 直接访问 `/budget` 不会加载 V1 页面
- 访问根路径 `/` 自动跳转到 V2 统计页面或返回 404
- V2 路由 (`/calendar-v2`, `/budget-v2`, `/statistics-v2`) 正常访问
---
## Dependencies
移除 V1 路由的前置条件:
1. V1 页面文件 (`CalendarView.vue`, `BudgetView.vue`, `statisticsV1/Index.vue`) 已删除
2. V2 页面功能已验证完整,可以完全替代 V1
3. 用户已迁移到 V2 版本,或系统强制使用 V2
移除后不影响:
- V2 路由配置和页面功能
- 路由守卫的认证检查逻辑 (`requiresAuth`)
- 其他非核心模块的路由 (如 `/login`, `/settings`)

View File

@@ -0,0 +1,141 @@
## REMOVED Requirements
### Requirement: Get Balance Statistics
**Reason**: 该接口仅被 V1 统计页面使用,用于绘制"余额变化折线图"。V2 统计页面使用不同的图表渲染逻辑,不依赖此接口。
**Migration**: V2 统计页面使用 `GetDailyStatistics` 接口获取数据,并在前端计算累积余额。无需后端专用接口。
**原有功能**:
- **接口**: `GET /api/TransactionStatistics/GetBalanceStatistics`
- **Controller**: `TransactionStatisticsController.GetBalanceStatisticsAsync`
- **参数**: `year` (int), `month` (int)
- **返回**: `BalanceStatisticsDto` (包含每日的累积余额数据)
- **业务逻辑**:
1. 查询指定月份的所有交易记录,按日期排序
2. 计算每日的累积余额 (前一日余额 + 当日收入 - 当日支出)
3. 返回包含日期和余额的时间序列数据
**被以下代码调用**:
- `Web/src/views/statisticsV1/Index.vue` 中的 `fetchBalanceData` 方法
- `Web/src/api/statistics.js` 中的 `getBalanceStatistics` 函数
**图表渲染逻辑**:
- V1 使用 ECharts 折线图渲染余额曲线
- 数据源: 后端计算好的累积余额
- 渲染方法: `renderBalanceChart()`
---
## Context
本规范定义了 EmailBill 后端 `TransactionStatisticsController` 中 V1 专用接口的移除操作。
### 接口背景
该接口是 V1 统计页面的核心功能之一,用于支持"余额变化趋势图"
- **设计理念**: 后端负责累积余额计算,前端只负责渲染
- **性能考虑**: 避免前端处理大量交易记录数据
- **适用场景**: V1 统计页面需要独立的余额统计视图
### V2 设计变更
V2 统计页面重新设计了数据获取和渲染逻辑:
- **数据获取**: 使用 `GetDailyStatistics` 一次性获取日度支出/收入数据
- **余额计算**: 在前端 Vue 组件中计算累积余额 (computed property)
- **性能优化**: 前端缓存计算结果,减少重复请求
- **代码简化**: 后端不需要维护专用的余额统计接口
### 技术对比
| 维度 | V1 实现 | V2 实现 |
|------|---------|---------|
| **数据获取** | 专用接口 `GetBalanceStatistics` | 通用接口 `GetDailyStatistics` |
| **余额计算** | 后端计算 | 前端计算 |
| **网络请求** | 2 次 (日度统计 + 余额统计) | 1 次 (日度统计) |
| **前端逻辑** | 简单渲染 | 计算 + 渲染 |
| **后端复杂度** | 高 (多个接口) | 低 (统一接口) |
### 依赖关系
该接口依赖以下 Service 和 Repository
- `TransactionStatisticsService.GetBalanceStatisticsAsync`
- `TransactionStatisticsApplication.GetBalanceStatisticsAsync`
- `TransactionRecordRepository` (查询交易记录)
移除接口后,相关 Service 方法也将被移除。
---
## Validation
### 验证标准
1. **代码搜索验证**:
- 全局搜索 `GetBalanceStatistics`,确认仅在以下位置出现:
- `TransactionStatisticsController.GetBalanceStatisticsAsync` (待删除)
- `TransactionStatisticsApplication.GetBalanceStatisticsAsync` (待删除)
- `TransactionStatisticsService.GetBalanceStatisticsAsync` (待删除)
- `statisticsV1/Index.vue` (已删除)
- `statistics.js` (已清理)
2. **编译验证**:
- 删除 `TransactionStatisticsController` 中的方法后,后端项目编译通过
- 删除 `TransactionStatisticsApplication``TransactionStatisticsService` 中的对应方法后,编译通过
3. **API 文档验证**:
- Swagger/Scalar 文档中不再显示 `/api/TransactionStatistics/GetBalanceStatistics` 端点
4. **运行时验证**:
- 前端调用 `/api/TransactionStatistics/GetBalanceStatistics` 返回 404
- V2 统计页面 (`/statistics-v2`) 正常加载,余额曲线正常渲染
5. **功能验证 (V2 统计页面)**:
- 打开 `/statistics-v2`
- 切换到"月度视图"
- 确认余额折线图正常显示
- 确认数据与 V1 保持一致 (基于相同的 `GetDailyStatistics` 数据)
---
## Dependencies
移除此接口的前置条件:
1. `statisticsV1/Index.vue` (V1 统计页面) 已删除
2. `Web/src/api/statistics.js` 中的 `getBalanceStatistics` 方法已清理
3. V2 统计页面已验证可以通过前端计算实现相同功能
移除后连带删除:
- `TransactionStatisticsApplication.GetBalanceStatisticsAsync`
- `TransactionStatisticsService.GetBalanceStatisticsAsync`
移除后不影响:
- 其他统计接口 (`GetMonthlyStatistics`, `GetCategoryStatistics`, `GetDailyStatistics`)
- `TransactionRecordRepository` 的查询逻辑 (仍被其他接口使用)
- V2 统计页面的任何功能 (余额计算逻辑已在前端实现)
---
## Implementation Notes
### V2 前端余额计算示例 (参考)
```javascript
// Web/src/views/statisticsV2/Index.vue
computed: {
balanceData() {
let cumulativeBalance = 0
return this.dailyData.map(day => {
cumulativeBalance += day.income - day.expense
return {
date: day.date,
balance: cumulativeBalance
}
})
}
}
```
### 性能分析
- **V1 方案**: 后端查询 + 计算 + 序列化 → 前端接收 + 渲染 (总时间: ~200ms)
- **V2 方案**: 后端查询 + 序列化 → 前端接收 + 计算 + 渲染 (总时间: ~180ms)
- **结论**: V2 方案性能略优,且减少了后端复杂度
### 回归测试建议
删除接口后,应手动验证 V2 统计页面的以下场景:
1. **正常月份**: 选择有交易的月份,确认余额曲线正常
2. **无交易月份**: 选择无交易的月份,确认显示"暂无数据"
3. **跨年场景**: 验证 1 月份的余额计算是否正确 (初始余额为 0)
4. **性能测试**: 加载包含大量交易 (>1000 笔) 的月份,确认渲染流畅

View File

@@ -0,0 +1,76 @@
## REMOVED Requirements
### Requirement: Get Daily Statistics (Obsolete)
**Reason**: 该接口已标记 `[Obsolete]`,仅被 V1 日历页面使用。V2 使用 `TransactionStatisticsController.GetDailyStatisticsAsync` 替代。
**Migration**: 前端应调用 `GET /api/TransactionStatistics/GetDailyStatistics` 接口,后端应使用 `TransactionStatisticsService.GetDailyStatisticsAsync` 方法。
**原有功能**:
- **接口**: `GET /api/TransactionRecord/GetDailyStatistics`
- **Controller**: `TransactionRecordController.GetDailyStatisticsAsync`
- **参数**: `year` (int), `month` (int)
- **返回**: `List<DailyStatisticDto>` (包含每日的支出、收入、余额统计)
**被以下代码调用**:
- `Web/src/views/CalendarView.vue` 中的 `fetchDailyStatistics` 方法
---
## Context
本规范定义了 EmailBill 后端 `TransactionRecordController` 中废弃的 V1 专用接口的移除操作。
### 接口历史
- **创建时间**: V1 版本早期,用于支持日历视图的日度统计
- **废弃原因**: 职责不清晰,日度统计应由 `TransactionStatisticsController` 统一管理
- **废弃标记**: 已标记 `[Obsolete]` 属性,建议开发者使用新接口
- **当前使用**: 仅被 `CalendarView.vue` (V1) 调用V2 日历页面不使用此接口
### 新接口对比
| 维度 | V1 接口 (待删除) | V2 接口 (推荐) |
|------|----------------|---------------|
| **路径** | `/api/TransactionRecord/GetDailyStatistics` | `/api/TransactionStatistics/GetDailyStatistics` |
| **Controller** | `TransactionRecordController` | `TransactionStatisticsController` |
| **职责** | 混杂在交易记录 CRUD 中 | 专注于统计查询 |
| **返回格式** | `List<DailyStatisticDto>` | 相同 |
| **性能** | 相同 | 相同 |
### 移除影响
- **前端**: `CalendarView.vue` 删除后,无其他前端代码调用此接口
- **后端**: `TransactionRecordController` 移除此方法后,不影响其他交易记录相关接口
- **数据库**: 无影响,底层查询逻辑由 `TransactionStatisticsService` 处理
---
## Validation
### 验证标准
1. **代码搜索验证**:
- 全局搜索 `GetDailyStatistics`,确认仅在以下位置出现:
- `TransactionRecordController.GetDailyStatisticsAsync` (待删除)
- `CalendarView.vue` (已删除)
- `TransactionStatisticsController.GetDailyStatisticsAsync` (保留)
2. **编译验证**:
- 删除 `TransactionRecordController.GetDailyStatisticsAsync` 方法后,后端项目编译通过
- 无其他 Controller 或 Application 层代码引用此方法
3. **API 文档验证**:
- Swagger/Scalar 文档中不再显示 `/api/TransactionRecord/GetDailyStatistics` 端点
- `/api/TransactionStatistics/GetDailyStatistics` 端点正常显示
4. **运行时验证**:
- 前端调用 `/api/TransactionRecord/GetDailyStatistics` 返回 404
- V2 日历页面调用 `/api/TransactionStatistics/GetDailyStatistics` 正常返回数据
---
## Dependencies
移除此接口的前置条件:
1. `CalendarView.vue` (V1 日历页面) 已删除
2. V2 日历页面已完全使用 `TransactionStatisticsController.GetDailyStatisticsAsync` 接口
移除后不影响:
- `TransactionStatisticsController` 中的同名方法 (不同 Controller)
- 其他交易记录相关接口 (`GetById`, `GetByDate`, `Update`, `Delete` 等)
- `TransactionRecordRepository` 的查询逻辑 (仍被 V2 接口使用)