## ADDED Requirements ### Requirement: 页面采用简洁的布局结构 预算 v2 页面 SHALL 采用简洁的布局结构,包含:DateSelectHeader、业务 tabs 和可滚动内容区域。 #### Scenario: 页面加载时显示完整布局 - **WHEN** 用户访问预算 v2 页面 - **THEN** 页面显示以下组件(从上到下): - DateSelectHeader(显示当前年月,左右箭头) - van-tabs(支出/收入/计划三个选项,默认选中"支出") - 可滚动内容区域(包含预算统计和列表) ### Requirement: 使用 DateSelectHeader 组件作为页头 预算 v2 页面 SHALL 使用 `@/components/DateSelectHeader.vue` 组件作为页头,替代当前的 `van-nav-bar`。 #### Scenario: 页头显示当前选中的年月 - **WHEN** 用户选择了 2024 年 3 月 - **THEN** 页头显示"2024年3月" #### Scenario: 点击左箭头切换到上一个月 - **WHEN** 用户点击页头左箭头 - **THEN** 切换到上一个月(如从 2024年3月 切换到 2024年2月) - **AND** 页面数据自动刷新 #### Scenario: 点击右箭头切换到下一个月 - **WHEN** 用户点击页头右箭头,且当前不是当前月 - **THEN** 切换到下一个月,页面数据自动刷新 #### Scenario: 当前是当前月时禁用右箭头 - **WHEN** 用户在当前月(如今天是 2024年3月15日,页面显示 2024年3月) - **THEN** 页头右箭头不可点击(不能查看未来月份) #### Scenario: 点击日期打开日期选择器 - **WHEN** 用户点击页头的日期文字 - **THEN** 显示年月选择器弹窗(van-date-picker,columns-type: ['year', 'month']) #### Scenario: 日期选择器不能选择未来月份 - **WHEN** 用户在日期选择器中尝试选择未来月份 - **THEN** 显示提示"不能选择未来的月份" - **AND** 不切换页面日期 ### Requirement: 业务 tabs 紧随页头之后 预算页面 SHALL 在 DateSelectHeader 下方直接显示业务 tabs(支出/收入/计划),使用 `van-tabs` 组件。 #### Scenario: 默认选中"支出" tab - **WHEN** 用户访问预算 v2 页面 - **THEN** 业务 tabs 默认选中"支出" #### Scenario: 切换到"收入" tab - **WHEN** 用户点击"收入" tab - **THEN** 内容区域显示收入预算的统计和列表 #### Scenario: 切换到"计划" tab - **WHEN** 用户点击"计划" tab - **THEN** 内容区域显示存款计划的列表 #### Scenario: 切换 tab 时保持页头日期不变 - **WHEN** 用户从"支出" tab 切换到"收入" tab - **THEN** 页头显示的年月不变 - **AND** 加载该月的收入预算数据 ### Requirement: 可滚动内容区域支持下拉刷新 内容区域 SHALL 支持下拉刷新,刷新当前选中的预算数据。 #### Scenario: 下拉刷新当前页面数据 - **WHEN** 用户在内容区域下拉 - **THEN** 显示刷新动画 - **AND** 重新加载当前月份和业务 tab 的数据 - **AND** 刷新完成后显示提示"刷新成功" ### Requirement: 支持左右滑动切换月份 预算页面 SHALL 支持在内容区域左右滑动来切换月份。 #### Scenario: 右滑切换到上一个月 - **WHEN** 用户在内容区域向右滑动超过 50px - **THEN** 切换到上一个月 - **AND** 页面数据自动刷新 #### Scenario: 左滑切换到下一个月 - **WHEN** 用户在内容区域向左滑动超过 50px,且不是当前月 - **THEN** 切换到下一个月 - **AND** 页面数据自动刷新 #### Scenario: 垂直滑动不触发月份切换 - **WHEN** 用户垂直滑动(滚动内容) - **THEN** 不触发月份切换 #### Scenario: 当前月时左滑不切换 - **WHEN** 用户在当前月向左滑动 - **THEN** 不切换到下一个月(不能查看未来月份) ### Requirement: 页面底部留出安全距离 内容区域 SHALL 在底部留出足够的安全距离,避免被底部导航栏遮挡。 #### Scenario: 内容区域底部安全距离 - **WHEN** 用户滚动到内容底部 - **THEN** 内容底部与底部导航栏之间有足够的间距(95px + env(safe-area-inset-bottom)) ### Requirement: 支持 keep-alive 缓存 预算 v2 页面 SHALL 支持 Vue Router 的 keep-alive 缓存,提升用户体验。 #### Scenario: 从其他页面返回时保持状态 - **WHEN** 用户从预算页面跳转到其他页面,然后返回 - **THEN** 预算页面保持之前的状态(选中的月份、业务 tab、滚动位置) #### Scenario: 接收全局事件刷新数据 - **WHEN** 用户在其他页面添加或修改了预算记录,触发 'transactions-changed' 事件 - **THEN** 预算页面自动刷新数据(如果页面处于激活状态) ### Requirement: 加载状态和错误处理 页面 SHALL 提供清晰的加载状态和错误提示。 #### Scenario: 数据加载中显示加载动画 - **WHEN** 页面正在加载预算数据 - **THEN** 显示加载动画(van-loading) #### Scenario: 数据加载失败显示错误提示 - **WHEN** 数据加载失败(网络错误、API 错误等) - **THEN** 显示错误提示(van-empty with error image) - **AND** 提供"重试"按钮 #### Scenario: 点击重试按钮重新加载 - **WHEN** 用户点击"重试"按钮 - **THEN** 清除错误状态 - **AND** 重新加载当前月份和业务 tab 的数据