From dea78bf04bdb62ccdb061d98e5b540bc71e67739 Mon Sep 17 00:00:00 2001 From: ila Date: Mon, 8 Jun 2026 15:40:04 +0800 Subject: [PATCH] stage 2: FIRE calculator, holdings tracker, settings store update - calculator.vue: compound-growth formula to compute months/date to FIRE, Barista FIRE logic breakdown card, collapsible editable params (bound to settings store) - holdings.vue: manual portfolio entry with add/edit/delete, P&L display - holdings.ts: new pinia store with persist; totalValue/Cost/PnL computed - settings.ts: add annualReturn (6% default) - progress.vue: enhanced empty-state onboarding prompt Co-Authored-By: Claude Sonnet 4.6 --- app/src/pages/calculator/calculator.vue | 217 +++++++++++++++++++++++- app/src/pages/holdings/holdings.vue | 215 ++++++++++++++++++++++- app/src/pages/progress/progress.vue | 15 +- app/src/store/holdings.ts | 42 +++++ app/src/store/settings.ts | 10 +- 5 files changed, 485 insertions(+), 14 deletions(-) create mode 100644 app/src/store/holdings.ts diff --git a/app/src/pages/calculator/calculator.vue b/app/src/pages/calculator/calculator.vue index 6786b41..9517ef0 100644 --- a/app/src/pages/calculator/calculator.vue +++ b/app/src/pages/calculator/calculator.vue @@ -1,14 +1,223 @@ diff --git a/app/src/pages/holdings/holdings.vue b/app/src/pages/holdings/holdings.vue index 15a96ee..0283632 100644 --- a/app/src/pages/holdings/holdings.vue +++ b/app/src/pages/holdings/holdings.vue @@ -1,14 +1,221 @@ diff --git a/app/src/pages/progress/progress.vue b/app/src/pages/progress/progress.vue index 31757e7..afded2a 100644 --- a/app/src/pages/progress/progress.vue +++ b/app/src/pages/progress/progress.vue @@ -83,8 +83,19 @@ function saveSnapshot() { 历史记录 - - 暂无记录,点击下方按钮录入 + + + 📊 + + + 记录你的第一笔净资产 + + + 净资产 = 所有存款 + 投资账户 − 负债
点击右下角 + 按钮录入当前总资产,开始追踪 FIRE 进度。 +
+ + 建议每月或每季度更新一次 +
{ + const holdings = ref([]) + + const totalValue = computed(() => holdings.value.reduce((s, h) => s + h.currentValue, 0)) + const totalCost = computed(() => holdings.value.reduce((s, h) => s + h.costBasis, 0)) + const totalPnl = computed(() => totalValue.value - totalCost.value) + const totalPnlPct = computed(() => + totalCost.value > 0 ? (totalPnl.value / totalCost.value) * 100 : 0, + ) + + function add(name: string, currentValue: number, costBasis: number) { + holdings.value.push({ + id: Date.now().toString(), + name, + currentValue, + costBasis, + }) + } + + function update(id: string, currentValue: number, costBasis: number) { + const h = holdings.value.find(h => h.id === id) + if (h) { + h.currentValue = currentValue + h.costBasis = costBasis + } + } + + function remove(id: string) { + holdings.value = holdings.value.filter(h => h.id !== id) + } + + return { holdings, totalValue, totalCost, totalPnl, totalPnlPct, add, update, remove } +}, { persist: true }) diff --git a/app/src/store/settings.ts b/app/src/store/settings.ts index 4c639fa..735535e 100644 --- a/app/src/store/settings.ts +++ b/app/src/store/settings.ts @@ -1,12 +1,13 @@ import { defineStore } from 'pinia' export const useSettingsStore = defineStore('settings', () => { - const target = ref(710000) // 目標本金(元) + const target = ref(710000) // 目标本金(元) const withdrawRate = ref(0.035) // 安全提取率 3.5% const monthlyInvest = ref(1500) // 每月定投(元) - const partTimeIncome = ref(40000) // 兼職年收入(元) - const annualExpense = ref(65000) // 年開支(元) - const initialCapital = ref(70000) // 起始本金(元) + const partTimeIncome = ref(40000) // 兼职年收入(元) + const annualExpense = ref(65000) // 年支出(元) + const initialCapital = ref(70000) // 起始本金(元),无进度记录时的回退值 + const annualReturn = ref(0.06) // 投资年化收益率 6% return { target, @@ -15,6 +16,7 @@ export const useSettingsStore = defineStore('settings', () => { partTimeIncome, annualExpense, initialCapital, + annualReturn, } }, { persist: true,