diff --git a/Web/src/App.vue b/Web/src/App.vue index 36f0eeb..73f99e1 100644 --- a/Web/src/App.vue +++ b/Web/src/App.vue @@ -58,7 +58,8 @@ const cachedViews = ref([ 'StatisticsView', // 统计页面 'StatisticsV2View', // 统计V2页面 'BalanceView', // 账单页面 - 'BudgetView' // 预算页面 + 'BudgetView', // 预算页面 + 'BudgetV2View' // 预算V2页面 ]) const updateVh = () => { @@ -156,7 +157,7 @@ const showNav = computed(() => { '/', '/statistics-v2', '/calendar', '/calendar-v2', '/balance', '/message', - '/budget', '/setting' + '/budget', '/budget-v2', '/setting' ].includes(route.path) }) diff --git a/Web/src/components/BudgetTypeTabs.vue b/Web/src/components/BudgetTypeTabs.vue new file mode 100644 index 0000000..e914788 --- /dev/null +++ b/Web/src/components/BudgetTypeTabs.vue @@ -0,0 +1,96 @@ + + + + + + diff --git a/Web/src/components/GlassBottomNav.vue b/Web/src/components/GlassBottomNav.vue index cc9111d..f79ffc1 100644 --- a/Web/src/components/GlassBottomNav.vue +++ b/Web/src/components/GlassBottomNav.vue @@ -44,7 +44,7 @@ const props = defineProps({ { name: 'calendar', label: '日历', icon: 'notes', path: '/calendar' }, { name: 'statistics', label: '统计', icon: 'chart-trending-o', path: '/' }, { name: 'balance', label: '账单', icon: 'balance-list', path: '/balance' }, - { name: 'budget', label: '预算', icon: 'bill-o', path: '/budget' }, + { name: 'budget', label: '预算', icon: 'bill-o', path: '/budget-v2' }, { name: 'setting', label: '设置', icon: 'setting', path: '/setting' } ] } diff --git a/Web/src/router/index.js b/Web/src/router/index.js index 9253cf3..24ef01b 100644 --- a/Web/src/router/index.js +++ b/Web/src/router/index.js @@ -107,6 +107,12 @@ const router = createRouter({ component: () => import('../views/BudgetView.vue'), meta: { requiresAuth: true } }, + { + path: '/budget-v2', + name: 'budget-v2', + component: () => import('../views/budgetV2/Index.vue'), + meta: { requiresAuth: true, keepAlive: true } + }, { path: '/scheduled-tasks', name: 'scheduled-tasks', diff --git a/Web/src/views/budgetV2/Index.vue b/Web/src/views/budgetV2/Index.vue new file mode 100644 index 0000000..3f35781 --- /dev/null +++ b/Web/src/views/budgetV2/Index.vue @@ -0,0 +1,1005 @@ + + + + + + diff --git a/Web/src/views/budgetV2/modules/ExpenseBudgetContent.vue b/Web/src/views/budgetV2/modules/ExpenseBudgetContent.vue new file mode 100644 index 0000000..7df6d9a --- /dev/null +++ b/Web/src/views/budgetV2/modules/ExpenseBudgetContent.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/Web/src/views/budgetV2/modules/IncomeBudgetContent.vue b/Web/src/views/budgetV2/modules/IncomeBudgetContent.vue new file mode 100644 index 0000000..7f4b8c1 --- /dev/null +++ b/Web/src/views/budgetV2/modules/IncomeBudgetContent.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/Web/src/views/budgetV2/modules/SavingsBudgetContent.vue b/Web/src/views/budgetV2/modules/SavingsBudgetContent.vue new file mode 100644 index 0000000..78060cb --- /dev/null +++ b/Web/src/views/budgetV2/modules/SavingsBudgetContent.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/Web/src/views/calendarV2/modules/Calendar.vue b/Web/src/views/calendarV2/modules/Calendar.vue index 013e5cc..07ff204 100644 --- a/Web/src/views/calendarV2/modules/Calendar.vue +++ b/Web/src/views/calendarV2/modules/Calendar.vue @@ -368,17 +368,17 @@ const getAriaLabel = (day) => { const date = new Date(day.date) const dateStr = formatDateKey(date) let label = dateStr - + if (day.isHoliday) { const type = day.isWorkday ? '调休工作日' : '休息日' label += ` ${day.holidayName} ${type}` } - + if (day.hasData) { const amountType = day.isProfitable ? '收入' : '支出' label += ` ${amountType} ${day.amount}元` } - + return label } diff --git a/openspec/changes/archive/2026-02-13-budget-page-v2/.openspec.yaml b/openspec/changes/archive/2026-02-13-budget-page-v2/.openspec.yaml new file mode 100644 index 0000000..95d284a --- /dev/null +++ b/openspec/changes/archive/2026-02-13-budget-page-v2/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-02-12 diff --git a/openspec/changes/archive/2026-02-13-budget-page-v2/design.md b/openspec/changes/archive/2026-02-13-budget-page-v2/design.md new file mode 100644 index 0000000..5dee28f --- /dev/null +++ b/openspec/changes/archive/2026-02-13-budget-page-v2/design.md @@ -0,0 +1,223 @@ +## Context + +当前预算页面(`BudgetView.vue`)是一个 1000+ 行的单文件组件,存在以下问题: +- 与 calendarV2、statisticsV2 风格不一致(页头和时间段切换设计不同) +- 数据加载逻辑复杂且存在 bug(未覆盖分类、存款计划切换、日期同步问题) +- 组件职责不清晰,难以维护 + +参考其他 v2 页面的经验,我们需要重构预算页面以实现: +1. 统一的页头设计(DateSelectHeader) +2. 模块化的组件结构(主页面 + 子模块) +3. 清晰的数据流和状态管理 +4. 简洁高效的用户体验(月度视图为主) + +**技术栈约束**: +- Vue 3 Composition API + `