From 49fb1b121f5d8813a01433ba0bb3c008d74dcea5 Mon Sep 17 00:00:00 2001 From: haotool Date: Sat, 27 Jun 2026 03:35:02 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(split-meow):=20=E6=B7=B7=E5=B9=A3?= =?UTF-8?q?=E8=A1=8C=E7=A8=8B=E5=8A=A0=E5=85=A5=20proactive=20=E9=98=BB?= =?UTF-8?q?=E6=93=8B=E8=88=87=E7=B7=A8=E8=BC=AF=E5=B9=A3=E5=88=A5=E5=B0=8D?= =?UTF-8?q?=E9=BD=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 wouldCreateMixedCurrencyTrip,切換全域幣別或存檔前先 confirm - 取消 confirm 不切幣別、不存檔,避免靜默產生混幣行程 - EditExpenseSheet 改用 resolveExpenseCurrency,修正 legacy 帳目幣別符號 - 沿用既有 history.mixed_currency_warning i18n key,未新增鍵 測試:vitest 184 項通過、tsc --noEmit 通過 --- ...lit-meow-mixed-currency-proactive-guard.md | 5 +++ apps/split-meow/src/components/Calculator.tsx | 17 +++++++++- apps/split-meow/src/components/HistoryTab.tsx | 4 ++- .../split-meow/src/components/SettingsTab.tsx | 18 ++++++++-- .../components/__tests__/Calculator.test.tsx | 33 ++++++++++++++++++- .../components/__tests__/SettingsTab.test.tsx | 29 +++++++++++++++- .../src/config/__tests__/currencies.test.ts | 10 ++++++ apps/split-meow/src/config/currencies.ts | 16 +++++++++ 8 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 .changeset/split-meow-mixed-currency-proactive-guard.md diff --git a/.changeset/split-meow-mixed-currency-proactive-guard.md b/.changeset/split-meow-mixed-currency-proactive-guard.md new file mode 100644 index 000000000..51f8633d7 --- /dev/null +++ b/.changeset/split-meow-mixed-currency-proactive-guard.md @@ -0,0 +1,5 @@ +--- +'@app/split-meow': patch +--- + +切換幣別或記帳若會使同一行程混用多種幣別,改在當下以確認對話框提示;編輯舊費用時改以行程主導幣別解析符號,避免顯示錯誤幣別。 diff --git a/apps/split-meow/src/components/Calculator.tsx b/apps/split-meow/src/components/Calculator.tsx index 7c53222f4..9e210517e 100644 --- a/apps/split-meow/src/components/Calculator.tsx +++ b/apps/split-meow/src/components/Calculator.tsx @@ -2,6 +2,7 @@ import { useTranslation } from 'react-i18next'; import { useStore } from '../store/useStore'; import { cn } from '../lib/utils'; import { evaluateExpression } from '../lib/evaluateExpression'; +import { wouldCreateMixedCurrencyTrip } from '../config/currencies'; interface CalculatorProps { onPawParticle?: (x: number, y: number) => void; @@ -17,6 +18,9 @@ export function Calculator({ onPawParticle }: CalculatorProps = {}) { setCalculatorValue, setItemizedValue, saveExpense, + expenses, + currentTripId, + currency, } = useStore(); const currentValue = @@ -31,6 +35,17 @@ export function Calculator({ onPawParticle }: CalculatorProps = {}) { ? evaluateExpression(currentValue) > 0 : Object.values(itemizedValues).some((v) => evaluateExpression(v) > 0); + const handleSave = () => { + const tripExpenses = expenses.filter((e) => e.tripId === currentTripId); + if ( + wouldCreateMixedCurrencyTrip(tripExpenses, currency, currency) && + !window.confirm(t('history.mixed_currency_warning')) + ) { + return; + } + saveExpense(); + }; + const handlePress = (key: string) => { if (splitMode === 'itemized' && !focusedMemberId) return; if ('vibrate' in navigator) navigator.vibrate(8); @@ -191,7 +206,7 @@ export function Calculator({ onPawParticle }: CalculatorProps = {}) { ))}