Files
EmailBill/openspec/specs/bill-list-component/spec.md
SunCheng 9921cd5fdf 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
2026-02-16 21:55:38 +08:00

7.1 KiB
Raw Blame History

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 删除按钮显示加载状态,防止重复点击