chore: migrate remaining ECharts components to Chart.js
- Migrated 4 components from ECharts to Chart.js: * MonthlyExpenseCard.vue (折线图) * DailyTrendChart.vue (双系列折线图) * ExpenseCategoryCard.vue (环形图) * BudgetChartAnalysis.vue (仪表盘 + 多种图表) - Removed all ECharts imports and environment variable switches - Unified all charts to use BaseChart.vue component - Build verified: pnpm build success ✓ - No echarts imports remaining ✓ Refs: openspec/changes/migrate-remaining-echarts-to-chartjs
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-15
|
||||
@@ -0,0 +1,260 @@
|
||||
## Context
|
||||
|
||||
当前 EmailBill 项目中存在两个 `TransactionList.vue` 实现:
|
||||
1. **旧版**(`Web/src/components/TransactionList.vue`):传统一行一卡片布局,功能完整但样式较旧
|
||||
2. **v2 版**(`Web/src/views/calendarV2/modules/TransactionList.vue`):现代卡片式设计,视觉层次更好
|
||||
|
||||
两个组件分别服务不同页面,导致:
|
||||
- 代码重复(格式化、API 调用、交互逻辑)
|
||||
- 样式不一致(用户体验割裂)
|
||||
- 维护成本高(修改需同步两处)
|
||||
|
||||
**技术栈约束:**
|
||||
- Vue 3 Composition API + `<script setup>` (JavaScript)
|
||||
- Vant UI 组件库(移动端)
|
||||
- Pinia 状态管理
|
||||
- 后端 API:`@/api/transactionRecord`
|
||||
|
||||
**重要说明:**
|
||||
- 项目使用 **JavaScript** 而非 TypeScript
|
||||
- 使用 JSDoc 注释提供类型提示
|
||||
- Props 和 Emits 使用 `defineProps()` 和 `defineEmits()` 的对象语法
|
||||
|
||||
**设计目标:**
|
||||
创建统一的 `BillListComponent.vue`,整合两者优点,高内聚设计,支持筛选、排序、分页、左滑删除、详情查看。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 创建可复用的账单列表组件 `BillListComponent.vue`(位于 `Web/src/components/Bill/`)
|
||||
- 基于 v2 风格,但调整为紧凑列表(非一行一卡片)
|
||||
- 内置筛选(类型、分类、日期范围)、排序(金额、时间)、分页加载
|
||||
- 支持左滑删除(van-swipe-cell)、点击详情(emit 事件)
|
||||
- 保留旧版的特殊功能(checkbox 选择模式)
|
||||
- 迁移所有使用旧组件的页面到新组件
|
||||
- 删除旧版 `Web/src/components/TransactionList.vue`
|
||||
|
||||
**Non-Goals:**
|
||||
- 不改变后端 API 接口
|
||||
- 不涉及新增数据字段
|
||||
- 不处理账单编辑功能(仅展示和删除)
|
||||
- 暂不支持拖拽排序
|
||||
|
||||
## Decisions
|
||||
|
||||
### 决策 1:组件命名和位置
|
||||
**选择**:`Web/src/components/Bill/BillListComponent.vue`
|
||||
|
||||
**理由**:
|
||||
- 放在 `Bill/` 目录下与现有 `BillForm.vue`、`ManualBillAdd.vue` 等保持一致
|
||||
- 命名为 `BillListComponent` 而非 `TransactionList`,避免与旧组件混淆
|
||||
- 符合项目 BEM 命名规范
|
||||
|
||||
**备选方案**:
|
||||
- 直接覆盖旧版 `TransactionList.vue` → **拒绝**:迁移期间需要并存,且容易引起冲突
|
||||
|
||||
### 决策 2:Props 设计(高内聚 vs 灵活配置)
|
||||
**选择**:**高内聚** - 组件内部管理筛选、排序、分页状态
|
||||
|
||||
**Props 定义**:
|
||||
```javascript
|
||||
// 使用 defineProps 对象语法 + JSDoc
|
||||
const props = defineProps({
|
||||
// 数据源模式
|
||||
dataSource: {
|
||||
type: String, // 'api' | 'custom'
|
||||
default: 'api'
|
||||
},
|
||||
|
||||
// API 模式参数
|
||||
apiParams: {
|
||||
type: Object, // { dateRange?: [string, string], category?: string, type?: 0|1|2 }
|
||||
default: () => ({})
|
||||
},
|
||||
|
||||
// Custom 模式参数
|
||||
transactions: {
|
||||
type: Array, // Transaction[]
|
||||
default: () => []
|
||||
},
|
||||
|
||||
// 功能开关
|
||||
showDelete: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showCheckbox: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
enableFilter: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
enableSort: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
|
||||
// 样式配置
|
||||
compact: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
|
||||
// 多选状态
|
||||
selectedIds: {
|
||||
type: Set,
|
||||
default: () => new Set()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
**理由**:
|
||||
- 大部分场景只需传 `apiParams`,组件自动处理筛选、排序、分页
|
||||
- `dataSource='custom'` 模式兼容特殊场景(如离线数据、缓存数据)
|
||||
- 功能开关满足不同页面需求(如 TransactionsRecord 需要 checkbox)
|
||||
|
||||
**备选方案**:
|
||||
- 低内聚(父组件管理所有状态)→ **拒绝**:每个使用方都要重复实现筛选、排序逻辑,违背复用目标
|
||||
|
||||
### 决策 3:筛选 UI 实现
|
||||
**选择**:`van-dropdown-menu` + `van-popup`(日期选择器)
|
||||
|
||||
**布局**:
|
||||
```
|
||||
[类型 ▼] [分类 ▼] [日期 ▼] [排序 ▼]
|
||||
```
|
||||
|
||||
**理由**:
|
||||
- Vant 的 `van-dropdown-menu` 适合移动端,节省空间
|
||||
- 日期范围选择使用 `van-calendar` 弹出层
|
||||
- 与项目现有 UI 风格一致
|
||||
|
||||
**备选方案**:
|
||||
- 使用 `van-tabs` 切换筛选项 → **拒绝**:占用空间大,不适合同时筛选多个维度
|
||||
|
||||
### 决策 4:数据加载策略
|
||||
**选择**:虚拟滚动 + 分页加载(`van-list`)
|
||||
|
||||
**实现**:
|
||||
- 初始加载 20 条
|
||||
- 滚动到底部触发 `@load` 事件,追加 20 条
|
||||
- 筛选/排序变更时,重置列表并重新加载
|
||||
|
||||
**理由**:
|
||||
- Vant 的 `van-list` 内置分页逻辑,简单易用
|
||||
- 账单数据量通常不大(日常使用 < 1000 条),无需复杂虚拟滚动库
|
||||
|
||||
**备选方案**:
|
||||
- 一次性加载全部数据 → **拒绝**:账单数量多时性能差
|
||||
|
||||
### 决策 5:删除功能的事务处理
|
||||
**选择**:组件内部调用 `deleteTransaction` API,删除成功后 emit 事件并派发全局事件
|
||||
|
||||
**流程**:
|
||||
```javascript
|
||||
const handleDelete = async (transaction) => {
|
||||
await showConfirmDialog({ message: '确定删除?' })
|
||||
await deleteTransaction(transaction.id) // API 调用
|
||||
emit('delete', transaction.id) // 通知父组件
|
||||
window.dispatchEvent(new CustomEvent('transaction-deleted', { detail: transaction.id })) // 全局事件
|
||||
// 刷新当前列表
|
||||
}
|
||||
```
|
||||
|
||||
**理由**:
|
||||
- 保持与旧版一致的删除逻辑(已验证可用)
|
||||
- 全局事件通知其他组件刷新(如统计图表)
|
||||
- 父组件可通过 `@delete` 监听执行额外逻辑
|
||||
|
||||
**备选方案**:
|
||||
- 父组件负责删除 → **拒绝**:增加使用成本,每个页面都要实现删除逻辑
|
||||
|
||||
### 决策 6:样式调整(紧凑列表)
|
||||
**选择**:修改 v2 的卡片布局,减少卡片间距和内边距
|
||||
|
||||
**调整细节**:
|
||||
```scss
|
||||
.bill-card {
|
||||
margin-top: 6px; // 原 10px
|
||||
padding: 10px 12px; // 原 var(--spacing-xl) (约 16px)
|
||||
gap: 10px; // 原 14px
|
||||
}
|
||||
```
|
||||
|
||||
**理由**:
|
||||
- v2 原始设计间距较大,适合日历单日视图
|
||||
- 列表视图需要更紧凑以显示更多条目
|
||||
- 保留 v2 的视觉元素(图标、标签、颜色)
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
### 风险 1:迁移期间功能遗漏
|
||||
**风险**:旧版组件可能有未文档化的特殊用法,迁移时遗漏
|
||||
**缓解措施**:
|
||||
- 迁移前全面梳理旧版所有 props 和 emits
|
||||
- 保留 `showCheckbox` 和 `selectedIds` 功能(TransactionsRecord 批量操作依赖)
|
||||
- 迁移分阶段进行,逐个页面验证
|
||||
|
||||
### 风险 2:性能退化
|
||||
**风险**:新增筛选、排序逻辑可能影响渲染性能
|
||||
**缓解措施**:
|
||||
- 使用 `computed` 缓存筛选结果
|
||||
- 大数据量时依赖后端 API 筛选(而非前端过滤)
|
||||
- 测试场景:1000+ 条数据的滚动流畅度
|
||||
|
||||
### 风险 3:样式兼容性
|
||||
**风险**:不同页面的主题色、暗黑模式可能导致显示异常
|
||||
**缓解措施**:
|
||||
- 使用 CSS 变量(`var(--van-danger-color)` 等),自动适配主题
|
||||
- 测试暗黑模式下的视觉效果
|
||||
- 提供 `themeOverride` prop 允许父组件覆盖样式
|
||||
|
||||
### Trade-off:组件复杂度 vs 易用性
|
||||
**权衡**:高内聚设计会增加组件内部复杂度(300+ 行代码)
|
||||
**选择**:接受复杂度换取易用性
|
||||
**理由**:
|
||||
- 简化所有使用方的代码(10+ 处引用)
|
||||
- 统一维护点,避免分散的重复逻辑
|
||||
- 内部复杂度可通过单元测试覆盖
|
||||
|
||||
## Migration Plan
|
||||
|
||||
### 阶段 1:组件开发(第 1-2 天)
|
||||
1. 创建 `Web/src/components/Bill/BillListComponent.vue`
|
||||
2. 实现核心功能:数据展示、分页、左滑删除
|
||||
3. 实现筛选、排序 UI 和逻辑
|
||||
4. 单元测试覆盖(Vue Test Utils)
|
||||
|
||||
### 阶段 2:试点迁移(第 3 天)
|
||||
1. 选择一个简单页面试点(如 `BillAnalysisView.vue`)
|
||||
2. 替换旧组件为新组件
|
||||
3. 验证功能完整性和视觉效果
|
||||
4. 修复发现的问题
|
||||
|
||||
### 阶段 3:全面迁移(第 4-5 天)
|
||||
1. 迁移 `TransactionsRecord.vue`(重点验证 checkbox 功能)
|
||||
2. 迁移其他引用旧组件的页面
|
||||
3. 回归测试所有相关页面
|
||||
|
||||
### 阶段 4:清理(第 6 天)
|
||||
1. 删除旧版 `Web/src/components/TransactionList.vue`
|
||||
2. 删除 `Web/src/views/calendarV2/modules/TransactionList.vue`(如不再需要)
|
||||
3. 更新文档和 AGENTS.md
|
||||
|
||||
### Rollback 策略
|
||||
- 保留旧版组件直到所有页面迁移完成
|
||||
- 使用 Git 分支隔离迁移工作
|
||||
- 如发现严重问题,可快速恢复旧版(修改 import 路径)
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **calendarV2 的 TransactionList 是否有特殊逻辑?**
|
||||
需要确认 calendarV2 是否依赖其特有功能(如 Smart 按钮、日期联动)。如果有,可能需要保留该文件,仅迁移其他页面。
|
||||
|
||||
2. **是否需要支持自定义列渲染?**
|
||||
当前设计固定显示字段(reason, amount, classify 等)。未来是否需要 slot 支持自定义?暂时不实现,等实际需求再扩展。
|
||||
|
||||
3. **筛选条件的持久化?**
|
||||
用户设置的筛选条件是否需要保存到 localStorage?当前设计不持久化,每次刷新恢复默认。
|
||||
@@ -0,0 +1,42 @@
|
||||
## Why
|
||||
|
||||
当前项目中存在多个账单列表实现(`TransactionList.vue` 在 `components/` 和 `calendarV2/modules/` 中),导致代码重复、样式不统一、维护成本高。v2 版本的账单列表(calendarV2/modules/TransactionList.vue)采用了更现代的卡片式设计和更好的视觉层次,应当作为标准组件在全项目范围内复用。
|
||||
|
||||
## What Changes
|
||||
|
||||
- **新增**:创建高内聚、可复用的 `BillListComponent.vue` 组件(基于 v2 风格)
|
||||
- **调整**:修改 v2 的一行一卡片布局,支持更紧凑的列表展示
|
||||
- **新增**:内置筛选(按类型、分类、日期)、排序(金额、时间)、分页功能
|
||||
- **新增**:左滑删除交互(Vant SwipeCell)
|
||||
- **新增**:点击查看详情功能(emit 事件)
|
||||
- **删除**:移除旧版本的 `TransactionList.vue`(Web/src/components/)
|
||||
- **迁移**:现有使用旧组件的页面(TransactionsRecord.vue、BillAnalysisView.vue 等)改为引用新组件
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `bill-list-component`: 可复用的账单列表组件,支持筛选、排序、分页、左滑删除、点击详情等功能,样式基于 calendarV2 的现代化设计
|
||||
|
||||
### Modified Capabilities
|
||||
- `transaction-list-display`: 现有的交易列表展示能力需要统一到新组件,旧版本 TransactionList.vue 的功能将被新组件替代
|
||||
|
||||
## Impact
|
||||
|
||||
**受影响的代码:**
|
||||
- `Web/src/components/TransactionList.vue` - 将被删除
|
||||
- `Web/src/views/calendarV2/modules/TransactionList.vue` - 作为参考基础,可能需要重构
|
||||
- `Web/src/views/TransactionsRecord.vue` - 需要切换到新组件
|
||||
- `Web/src/views/BillAnalysisView.vue` - 需要切换到新组件
|
||||
- 其他可能引用旧版 TransactionList 的视图
|
||||
|
||||
**API 依赖:**
|
||||
- `@/api/transactionRecord` - deleteTransaction, getTransactionsByDate 等接口
|
||||
- 保持现有 API 调用方式不变
|
||||
|
||||
**UI 依赖:**
|
||||
- Vant UI: van-swipe-cell, van-list, van-loading, van-empty, van-icon, van-tag
|
||||
- 需要新增筛选/排序 UI 组件(van-dropdown-menu, van-popup)
|
||||
|
||||
**用户体验影响:**
|
||||
- 正面:统一的视觉风格、更流畅的交互、更好的性能(高内聚设计)
|
||||
- 迁移风险:需要确保功能对等,避免遗漏旧版本的特殊功能(如 checkbox 选择模式)
|
||||
@@ -0,0 +1,191 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Component accepts configuration props
|
||||
组件必须接受配置 props 以支持不同的使用场景,包括数据源模式、功能开关、样式配置等。
|
||||
|
||||
#### Scenario: API 数据源模式
|
||||
- **WHEN** 父组件传入 `dataSource="api"` 和 `apiParams={ dateRange: ['2026-01-01', '2026-01-31'] }`
|
||||
- **THEN** 组件调用后端 API 获取指定日期范围内的账单数据
|
||||
|
||||
#### Scenario: 自定义数据源模式
|
||||
- **WHEN** 父组件传入 `dataSource="custom"` 和 `transactions` 数组
|
||||
- **THEN** 组件直接使用传入的数据进行展示,不调用 API
|
||||
|
||||
#### Scenario: 禁用筛选功能
|
||||
- **WHEN** 父组件传入 `enableFilter={false}`
|
||||
- **THEN** 组件不显示筛选栏(类型、分类、日期下拉菜单)
|
||||
|
||||
#### Scenario: 启用多选模式
|
||||
- **WHEN** 父组件传入 `showCheckbox={true}`
|
||||
- **THEN** 每个账单项左侧显示复选框,支持多选
|
||||
|
||||
### Requirement: 账单列表展示
|
||||
组件必须以紧凑列表形式展示账单数据,每个账单项包含关键信息(摘要、金额、分类、时间)。
|
||||
|
||||
#### Scenario: 展示支出账单
|
||||
- **WHEN** 账单类型为支出(type=0)
|
||||
- **THEN** 金额显示为红色负数(如 "- ¥50.00"),右上角显示红色"支出"标签
|
||||
|
||||
#### Scenario: 展示收入账单
|
||||
- **WHEN** 账单类型为收入(type=1)
|
||||
- **THEN** 金额显示为绿色正数(如 "+ ¥1000.00"),右上角显示绿色"收入"标签
|
||||
|
||||
#### Scenario: 显示账单图标
|
||||
- **WHEN** 账单有分类信息(如"餐饮")
|
||||
- **THEN** 卡片左侧显示对应的图标(如 food 图标),背景色与分类关联
|
||||
|
||||
#### Scenario: 空列表状态
|
||||
- **WHEN** 筛选结果为空或无账单数据
|
||||
- **THEN** 显示空状态提示"暂无交易记录",带有图标和友好文案
|
||||
|
||||
### Requirement: 筛选功能
|
||||
组件必须提供内置的筛选功能,支持按类型、分类、日期范围筛选账单。
|
||||
|
||||
#### Scenario: 按类型筛选
|
||||
- **WHEN** 用户在筛选栏选择"支出"
|
||||
- **THEN** 列表仅显示类型为支出的账单(type=0)
|
||||
|
||||
#### Scenario: 按分类筛选
|
||||
- **WHEN** 用户在筛选栏选择"餐饮"
|
||||
- **THEN** 列表仅显示分类为"餐饮"的账单
|
||||
|
||||
#### Scenario: 按日期范围筛选
|
||||
- **WHEN** 用户选择日期范围"2026-02-01 至 2026-02-15"
|
||||
- **THEN** 列表仅显示该日期范围内的账单
|
||||
|
||||
#### Scenario: 多条件组合筛选
|
||||
- **WHEN** 用户同时选择"支出"、"餐饮"和日期范围
|
||||
- **THEN** 列表显示满足所有条件的账单(AND 逻辑)
|
||||
|
||||
#### Scenario: 清空筛选条件
|
||||
- **WHEN** 用户点击"重置"或清空所有筛选项
|
||||
- **THEN** 列表恢复显示全部账单
|
||||
|
||||
### Requirement: 排序功能
|
||||
组件必须支持按金额或时间排序账单列表。
|
||||
|
||||
#### Scenario: 按金额降序排序
|
||||
- **WHEN** 用户在排序下拉菜单选择"金额从高到低"
|
||||
- **THEN** 列表按金额降序重新排列
|
||||
|
||||
#### Scenario: 按时间升序排序
|
||||
- **WHEN** 用户在排序下拉菜单选择"时间从早到晚"
|
||||
- **THEN** 列表按交易时间升序排列
|
||||
|
||||
#### Scenario: 默认排序
|
||||
- **WHEN** 组件初始加载且用户未设置排序
|
||||
- **THEN** 列表按时间降序排列(最新的在前)
|
||||
|
||||
### Requirement: 分页加载
|
||||
组件必须支持滚动分页加载,优化大数据量时的性能。
|
||||
|
||||
#### Scenario: 初始加载
|
||||
- **WHEN** 组件首次渲染
|
||||
- **THEN** 加载前 20 条账单数据并显示
|
||||
|
||||
#### Scenario: 滚动加载更多
|
||||
- **WHEN** 用户滚动到列表底部
|
||||
- **THEN** 自动加载下一页 20 条数据并追加到列表
|
||||
|
||||
#### Scenario: 加载完成提示
|
||||
- **WHEN** 所有数据加载完毕
|
||||
- **THEN** 列表底部显示"没有更多了"提示
|
||||
|
||||
#### Scenario: 筛选后重新分页
|
||||
- **WHEN** 用户修改筛选条件
|
||||
- **THEN** 列表重置到第一页,重新开始分页加载
|
||||
|
||||
### Requirement: 左滑删除功能
|
||||
组件必须支持左滑显示删除按钮,并处理删除操作。
|
||||
|
||||
#### Scenario: 左滑显示删除按钮
|
||||
- **WHEN** 用户在账单项上左滑
|
||||
- **THEN** 右侧显示红色"删除"按钮
|
||||
|
||||
#### Scenario: 确认删除
|
||||
- **WHEN** 用户点击"删除"按钮并在确认对话框中选择"确定"
|
||||
- **THEN** 调用 API 删除该账单,成功后从列表移除,显示"删除成功"提示
|
||||
|
||||
#### Scenario: 取消删除
|
||||
- **WHEN** 用户点击"删除"按钮并在确认对话框中选择"取消"
|
||||
- **THEN** 不执行删除操作,滑块自动归位
|
||||
|
||||
#### Scenario: 删除失败处理
|
||||
- **WHEN** API 删除失败(如网络错误)
|
||||
- **THEN** 显示"删除失败"提示,列表不变
|
||||
|
||||
#### Scenario: 删除后广播事件
|
||||
- **WHEN** 账单删除成功
|
||||
- **THEN** 组件派发全局事件 `transaction-deleted`,携带删除的账单 ID
|
||||
|
||||
#### Scenario: 禁用删除功能
|
||||
- **WHEN** 父组件传入 `showDelete={false}`
|
||||
- **THEN** 左滑不显示删除按钮
|
||||
|
||||
### Requirement: 点击查看详情
|
||||
组件必须支持点击账单项查看详情,通过 emit 事件通知父组件。
|
||||
|
||||
#### Scenario: 点击账单卡片
|
||||
- **WHEN** 用户点击账单项(非复选框、非删除按钮区域)
|
||||
- **THEN** 组件触发 `@click` 事件,传递完整的账单对象
|
||||
|
||||
#### Scenario: 父组件处理详情显示
|
||||
- **WHEN** 父组件监听 `@click` 事件
|
||||
- **THEN** 父组件接收账单对象,自行决定详情展示方式(如弹窗、路由跳转)
|
||||
|
||||
### Requirement: 多选功能
|
||||
组件必须支持多选模式,用于批量操作场景。
|
||||
|
||||
#### Scenario: 启用多选模式
|
||||
- **WHEN** 父组件传入 `showCheckbox={true}`
|
||||
- **THEN** 每个账单项左侧显示复选框
|
||||
|
||||
#### Scenario: 选中账单
|
||||
- **WHEN** 用户点击复选框
|
||||
- **THEN** 该账单被标记为选中状态,复选框显示勾选
|
||||
|
||||
#### Scenario: 取消选中
|
||||
- **WHEN** 用户再次点击已选中的复选框
|
||||
- **THEN** 该账单取消选中状态
|
||||
|
||||
#### Scenario: 同步选中状态
|
||||
- **WHEN** 父组件更新 `selectedIds` prop
|
||||
- **THEN** 组件更新复选框的选中状态以匹配传入的 ID 集合
|
||||
|
||||
#### Scenario: 通知父组件选中变更
|
||||
- **WHEN** 用户切换复选框状态
|
||||
- **THEN** 组件触发 `@update:selectedIds` 事件,传递新的选中 ID 集合
|
||||
|
||||
### Requirement: 样式适配
|
||||
组件必须适配移动端主题和暗黑模式。
|
||||
|
||||
#### Scenario: 亮色主题
|
||||
- **WHEN** 应用使用亮色主题
|
||||
- **THEN** 组件使用浅色背景、深色文字,边框和标签使用主题色
|
||||
|
||||
#### Scenario: 暗黑模式
|
||||
- **WHEN** 应用切换到暗黑模式
|
||||
- **THEN** 组件使用深色背景、浅色文字,自动适配 Vant 的暗黑主题变量
|
||||
|
||||
#### Scenario: 紧凑模式
|
||||
- **WHEN** 父组件传入 `compact={true}`(默认)
|
||||
- **THEN** 卡片间距为 6px,内边距为 10px,显示更多条目
|
||||
|
||||
#### Scenario: 舒适模式
|
||||
- **WHEN** 父组件传入 `compact={false}`
|
||||
- **THEN** 卡片间距和内边距增大(如 v2 原始尺寸)
|
||||
|
||||
### Requirement: 加载状态
|
||||
组件必须显示加载状态,提供良好的用户反馈。
|
||||
|
||||
#### Scenario: 首次加载中
|
||||
- **WHEN** 组件调用 API 获取数据且尚未返回
|
||||
- **THEN** 显示加载动画(van-loading)和"加载中..."文案
|
||||
|
||||
#### Scenario: 分页加载中
|
||||
- **WHEN** 用户滚动触发分页加载
|
||||
- **THEN** 列表底部显示加载动画
|
||||
|
||||
#### Scenario: 删除操作中
|
||||
- **WHEN** 用户点击删除且 API 调用进行中
|
||||
- **THEN** 删除按钮显示加载状态,防止重复点击
|
||||
@@ -0,0 +1,59 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 统一组件实现
|
||||
系统必须使用统一的 BillListComponent 替代现有的多个账单列表实现,确保代码复用和样式一致性。
|
||||
|
||||
#### Scenario: 替换旧版 TransactionList
|
||||
- **WHEN** 页面需要展示账单列表
|
||||
- **THEN** 使用 `BillListComponent.vue` 而非 `components/TransactionList.vue`
|
||||
|
||||
#### Scenario: CalendarV2 模块迁移
|
||||
- **WHEN** CalendarV2 需要展示交易列表
|
||||
- **THEN** 使用 `BillListComponent.vue` 或保留其特有实现(如有特殊需求)
|
||||
|
||||
### Requirement: 功能对等性
|
||||
新组件必须保持旧版所有功能,确保迁移不丢失特性。
|
||||
|
||||
#### Scenario: 批量选择功能
|
||||
- **WHEN** TransactionsRecord 需要批量操作
|
||||
- **THEN** 新组件通过 `showCheckbox` 和 `selectedIds` 提供相同功能
|
||||
|
||||
#### Scenario: 删除后刷新
|
||||
- **WHEN** 账单删除成功
|
||||
- **THEN** 新组件派发 `transaction-deleted` 全局事件,保持与旧版相同的事件机制
|
||||
|
||||
#### Scenario: 自定义数据源
|
||||
- **WHEN** 页面需要展示离线或缓存数据
|
||||
- **THEN** 新组件通过 `dataSource="custom"` 和 `transactions` prop 支持自定义数据
|
||||
|
||||
### Requirement: 视觉升级
|
||||
新组件必须基于 v2 的现代化设计,提供更好的视觉体验。
|
||||
|
||||
#### Scenario: 卡片样式
|
||||
- **WHEN** 展示账单列表
|
||||
- **THEN** 使用 v2 的卡片样式(圆角、阴影、图标),但调整为紧凑间距
|
||||
|
||||
#### Scenario: 图标展示
|
||||
- **WHEN** 账单有分类信息
|
||||
- **THEN** 显示对应的分类图标(如餐饮用 food 图标),带有彩色背景
|
||||
|
||||
#### Scenario: 标签样式
|
||||
- **WHEN** 显示账单类型
|
||||
- **THEN** 使用彩色标签(支出红色、收入绿色),位于卡片右上角
|
||||
|
||||
### Requirement: 迁移计划
|
||||
系统必须按阶段迁移,确保平滑过渡。
|
||||
|
||||
#### Scenario: 并存期
|
||||
- **WHEN** 迁移进行中
|
||||
- **THEN** 新旧组件共存,已迁移页面使用新组件,未迁移页面继续使用旧组件
|
||||
|
||||
#### Scenario: 清理旧代码
|
||||
- **WHEN** 所有页面迁移完成
|
||||
- **THEN** 删除 `components/TransactionList.vue`,移除相关 import
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: 一行一卡片布局
|
||||
**Reason**: 间距过大,不适合列表视图,需要滚动过多才能查看更多账单
|
||||
**Migration**: 使用新的紧凑布局(`compact={true}`),卡片间距减少至 6px
|
||||
@@ -0,0 +1,135 @@
|
||||
## 1. 组件基础结构搭建
|
||||
|
||||
- [x] 1.1 创建 `Web/src/components/Bill/BillListComponent.vue` 文件
|
||||
- [x] 1.2 定义 TypeScript Props 接口(dataSource, apiParams, transactions, showDelete, showCheckbox, enableFilter, enableSort, compact)
|
||||
- [x] 1.3 定义 Emits 接口(load, click, delete, update:selectedIds)
|
||||
- [x] 1.4 创建组件骨架(template、script setup、style scoped)
|
||||
- [x] 1.5 添加必要的 Vant 组件导入(van-list, van-swipe-cell, van-dropdown-menu, van-loading, van-empty, van-icon, van-tag)
|
||||
|
||||
## 2. 数据管理和状态
|
||||
|
||||
- [x] 2.1 实现 `dataSource` 模式切换逻辑(api vs custom)
|
||||
- [x] 2.2 创建响应式数据状态(transactions, loading, finished, page, pageSize)
|
||||
- [x] 2.3 实现筛选状态管理(selectedType, selectedCategory, dateRange, sortBy)
|
||||
- [x] 2.4 实现多选状态管理(localSelectedIds, 与 prop 同步)
|
||||
- [x] 2.5 创建 computed 计算属性用于筛选和排序逻辑
|
||||
|
||||
## 3. API 数据加载
|
||||
|
||||
- [x] 3.1 导入 `@/api/transactionRecord` 的相关 API 方法
|
||||
- [x] 3.2 实现初始加载逻辑(fetchTransactions 方法)
|
||||
- [x] 3.3 实现分页加载逻辑(onLoad 方法,支持 van-list)
|
||||
- [x] 3.4 实现筛选条件变更时的数据重载逻辑
|
||||
- [x] 3.5 处理 API 错误和加载状态
|
||||
|
||||
## 4. 筛选功能实现
|
||||
|
||||
- [x] 4.1 创建筛选栏 UI(van-dropdown-menu,包含类型、分类、日期、排序四个下拉菜单)
|
||||
- [x] 4.2 实现类型筛选(支出、收入、不计入、全部)
|
||||
- [x] 4.3 实现分类筛选(动态获取分类列表或预设常用分类)
|
||||
- [x] 4.4 实现日期范围筛选(使用 van-calendar 弹出层)
|
||||
- [x] 4.5 实现排序功能(金额降序、金额升序、时间降序、时间升序)
|
||||
- [x] 4.6 添加筛选重置功能
|
||||
- [x] 4.7 根据 `enableFilter` prop 控制筛选栏显示/隐藏
|
||||
|
||||
## 5. 账单列表展示
|
||||
|
||||
- [x] 5.1 创建账单卡片布局(基于 v2 风格,左侧图标、中间内容、右侧金额)
|
||||
- [x] 5.2 实现紧凑模式样式(减少卡片间距至 6px,内边距至 10px)
|
||||
- [x] 5.3 实现账单图标显示(根据分类映射图标,使用 getIconByClassify 方法)
|
||||
- [x] 5.4 实现金额格式化(带符号、颜色区分支出/收入)
|
||||
- [x] 5.5 实现类型标签显示(右上角,支出红色、收入绿色)
|
||||
- [x] 5.6 实现时间格式化显示(HH:MM 或 YYYY-MM-DD HH:MM)
|
||||
- [x] 5.7 实现空状态展示(van-empty,带友好文案)
|
||||
|
||||
## 6. 左滑删除功能
|
||||
|
||||
- [x] 6.1 为每个账单项添加 van-swipe-cell 包裹
|
||||
- [x] 6.2 创建删除按钮插槽(右侧滑出,红色按钮)
|
||||
- [x] 6.3 实现删除确认对话框(van-dialog)
|
||||
- [x] 6.4 实现删除 API 调用(deleteTransaction)
|
||||
- [x] 6.5 删除成功后更新本地列表(移除对应项)
|
||||
- [x] 6.6 显示删除成功/失败提示(van-toast)
|
||||
- [x] 6.7 派发全局事件 `transaction-deleted`
|
||||
- [x] 6.8 触发父组件 `@delete` 事件
|
||||
- [x] 6.9 根据 `showDelete` prop 控制删除功能启用/禁用
|
||||
|
||||
## 7. 点击详情功能
|
||||
|
||||
- [x] 7.1 为账单卡片添加 @click 事件监听
|
||||
- [x] 7.2 实现 handleClick 方法,触发 `@click` 事件并传递账单对象
|
||||
- [x] 7.3 确保点击复选框或删除按钮时不触发详情事件(事件冒泡处理)
|
||||
|
||||
## 8. 多选功能
|
||||
|
||||
- [x] 8.1 在账单项左侧添加 van-checkbox(根据 `showCheckbox` prop 控制显示)
|
||||
- [x] 8.2 实现 checkbox 选中状态与 `selectedIds` prop 同步
|
||||
- [x] 8.3 实现 toggleSelection 方法(切换选中状态)
|
||||
- [x] 8.4 触发 `@update:selectedIds` 事件更新父组件状态
|
||||
- [ ] 8.5 添加全选/取消全选功能(可选,视需求)
|
||||
|
||||
## 9. 样式和主题适配
|
||||
|
||||
- [x] 9.1 使用 SCSS 编写组件样式
|
||||
- [x] 9.2 使用 CSS 变量适配 Vant 主题(`var(--van-danger-color)` 等)
|
||||
- [x] 9.3 实现暗黑模式适配(检查暗色背景下的显示效果)
|
||||
- [x] 9.4 根据 `compact` prop 调整卡片间距和内边距
|
||||
- [x] 9.5 确保移动端响应式布局(处理小屏幕、横屏等情况)
|
||||
- [x] 9.6 添加过渡动画(卡片删除、列表加载等)
|
||||
|
||||
## 10. 页面迁移 - TransactionsRecord
|
||||
|
||||
- [x] 10.1 在 `TransactionsRecord.vue` 中导入新组件 `BillListComponent`
|
||||
- [x] 10.2 替换旧 `TransactionList` 组件为 `BillListComponent`
|
||||
- [x] 10.3 传递必要的 props(showCheckbox, selectedIds, apiParams)
|
||||
- [x] 10.4 更新事件监听(@click, @delete, @update:selectedIds)
|
||||
- [ ] 10.5 验证批量操作功能正常(选中、删除、导出等)
|
||||
- [ ] 10.6 测试页面功能完整性
|
||||
|
||||
## 11. 页面迁移 - BillAnalysisView
|
||||
|
||||
- [x] 11.1 在 `BillAnalysisView.vue` 中导入新组件 `BillListComponent` (页面未使用旧组件,跳过)
|
||||
- [x] 11.2 替换旧组件为 `BillListComponent` (页面未使用旧组件,跳过)
|
||||
- [x] 11.3 传递筛选参数(如按分类、日期范围)(页面未使用旧组件,跳过)
|
||||
- [x] 11.4 更新事件监听 (页面未使用旧组件,跳过)
|
||||
- [x] 11.5 测试页面功能正常 (页面未使用旧组件,跳过)
|
||||
|
||||
## 12. 页面迁移 - 其他引用页面
|
||||
|
||||
- [x] 12.1 使用 grep 搜索所有引用旧 `TransactionList` 的文件
|
||||
- [x] 12.2 逐个页面进行迁移(重复步骤 10-11 的流程)
|
||||
- [x] 12.3 验证每个页面的功能和样式
|
||||
- [x] 12.4 检查是否有遗漏的引用
|
||||
|
||||
## 13. CalendarV2 模块处理
|
||||
|
||||
- [x] 13.1 评估 `calendarV2/modules/TransactionList.vue` 的特殊功能(Smart 按钮、日期联动等)
|
||||
- [x] 13.2 决定是保留该文件还是迁移到新组件
|
||||
- [x] 13.3 如保留,添加注释说明其特殊性;如迁移,确保功能对等
|
||||
- [x] 13.4 测试 CalendarV2 的交易列表功能
|
||||
|
||||
## 14. 清理旧代码
|
||||
|
||||
- [x] 14.1 删除 `Web/src/components/TransactionList.vue`
|
||||
- [x] 14.2 检查并删除相关的未使用导入
|
||||
- [x] 14.3 更新 `AGENTS.md` 或相关文档,说明新组件的使用方式
|
||||
- [x] 14.4 提交代码变更(Git commit)
|
||||
|
||||
## 15. 测试和验证
|
||||
|
||||
- [ ] 15.1 编写单元测试(Vue Test Utils,测试 props、emits、筛选、排序逻辑)
|
||||
- [ ] 15.2 手动测试所有功能点(筛选、排序、分页、删除、多选、详情)
|
||||
- [ ] 15.3 测试暗黑模式显示效果
|
||||
- [ ] 15.4 测试不同屏幕尺寸的响应式布局
|
||||
- [ ] 15.5 测试 API 错误处理和边界情况(空数据、网络错误等)
|
||||
- [ ] 15.6 回归测试所有迁移页面,确保无功能丢失
|
||||
- [ ] 15.7 性能测试(加载 1000+ 条数据时的流畅度)
|
||||
|
||||
## 16. 文档和收尾
|
||||
|
||||
- [x] 16.1 编写组件使用文档(Props、Emits、Slots 说明)
|
||||
- [x] 16.2 更新 `Web/src/views/AGENTS.md`(如有)
|
||||
- [x] 16.3 在组件文件顶部添加 JSDoc 注释
|
||||
- [x] 16.4 代码格式化(pnpm lint)
|
||||
- [x] 16.5 构建测试(pnpm build)
|
||||
- [x] 16.6 最终代码审查
|
||||
Reference in New Issue
Block a user