support changing numeral system

This commit is contained in:
MaysWind
2025-08-17 01:55:19 +08:00
parent ab6d4ee6fc
commit cd4d230d29
59 changed files with 1153 additions and 582 deletions
@@ -202,7 +202,7 @@
<v-skeleton-loader class="skeleton-no-margin ml-3" type="text" style="width: 80px" :loading="true"></v-skeleton-loader>
</span>
<span class="ml-2" v-else-if="!loading">
{{ reconciliationStatements?.transactions.length ?? 0 }}
{{ formatNumberToLocalizedNumerals(reconciliationStatements?.transactions.length ?? 0) }}
</span>
<v-spacer/>
<span v-if="reconciliationStatements && reconciliationStatements.transactions && reconciliationStatements.transactions.length > 10">
@@ -319,7 +319,7 @@ const emit = defineEmits<{
(e: 'error', message: string): void;
}>();
const { tt } = useI18n();
const { tt, formatNumberToLocalizedNumerals } = useI18n();
const {
accountId,
+25 -7
View File
@@ -118,7 +118,7 @@
density="comfortable" variant="text"
:class="{ 'd-none': loading, 'hover-display': !loading }"
v-if="exchangeRate.currencyCode !== baseCurrency"
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate))">
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate, false))">
{{ tt('Set as Base') }}
</v-btn>
<v-btn class="px-2" color="default"
@@ -134,7 +134,7 @@
</template>
{{ tt('Delete') }}
</v-btn>
<span class="ml-3">{{ getFinalConvertedAmount(exchangeRate) }}</span>
<span class="ml-3">{{ getFinalConvertedAmount(exchangeRate, true) }}</span>
</div>
</td>
</tr>
@@ -168,6 +168,8 @@ import { useExchangeRatesPageBase } from '@/views/base/ExchangeRatesPageBase.ts'
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
import { NumeralSystem } from '@/core/numeral.ts';
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
import logger from '@/lib/logger.ts';
@@ -184,7 +186,7 @@ type UpdateDialogType = InstanceType<typeof UpdateDialog>;
const { mdAndUp } = useDisplay();
const { tt, formatExchangeRateAmount } = useI18n();
const { tt, getCurrentNumeralSystemType, formatExchangeRateAmountToWesternArabicNumerals } = useI18n();
const {
baseCurrency,
baseAmount,
@@ -283,9 +285,15 @@ function remove(currency: string): void {
});
}
function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate): string {
function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate, displayLocalizedDigits: boolean): string {
const numeralSystem = getCurrentNumeralSystemType();
if (!baseCurrency.value) {
return '0';
if (displayLocalizedDigits) {
return numeralSystem.digitZero;
} else {
return NumeralSystem.WesternArabicNumerals.digitZero;
}
}
const fromExchangeRate = exchangeRatesStore.latestExchangeRateMap[baseCurrency.value];
@@ -299,10 +307,20 @@ function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate): s
}
if (!exchangeRateAmount) {
return '0';
if (displayLocalizedDigits) {
return numeralSystem.digitZero;
} else {
return NumeralSystem.WesternArabicNumerals.digitZero;
}
}
return formatExchangeRateAmount(exchangeRateAmount);
let ret = formatExchangeRateAmountToWesternArabicNumerals(exchangeRateAmount);
if (displayLocalizedDigits) {
ret = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(ret);
}
return ret;
}
watch(mdAndUp, (newValue) => {
@@ -34,8 +34,12 @@ import { useI18n } from '@/locales/helpers.ts';
import { useSettingsStore } from '@/stores/setting.ts';
import { useUserStore } from '@/stores/user.ts';
import type { HiddenAmount } from '@/core/numeral.ts';
import { TransactionType } from '@/core/transaction.ts';
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
import { type TransactionMonthlyIncomeAndExpenseData } from '@/models/transaction.ts';
import {
parseDateFromUnixTime,
getMonthName
@@ -59,7 +63,7 @@ const emit = defineEmits<{
(e: 'click', event: MonthlyIncomeAndExpenseCardClickEvent): void;
}>();
const { tt, getMonthShortName, formatAmountWithCurrency } = useI18n();
const { tt, getMonthShortName, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
const settingsStore = useSettingsStore();
const userStore = useUserStore();
@@ -275,16 +279,16 @@ const chartOptions = computed<object>(() => {
};
});
function getDisplayCurrency(value: number | string, currencyCode: string): string {
return formatAmountWithCurrency(value, currencyCode);
function getDisplayCurrency(value: number | HiddenAmount, currencyCode: string): string {
return formatAmountToLocalizedNumeralsWithCurrency(value, currencyCode);
}
function getDisplayAmount(amount: number, incomplete: boolean): string {
if (!showAmountInHomePage.value) {
return getDisplayCurrency('***', defaultCurrency.value);
return getDisplayCurrency(DISPLAY_HIDDEN_AMOUNT, defaultCurrency.value);
}
return getDisplayCurrency(amount, defaultCurrency.value) + (incomplete ? '+' : '');
return getDisplayCurrency(amount, defaultCurrency.value) + (incomplete ? INCOMPLETE_AMOUNT_SUFFIX : '');
}
function getDisplayIncomeAmount(data: TransactionMonthlyIncomeAndExpenseData): string {
@@ -238,7 +238,7 @@
<div class="d-flex flex-column ml-2">
<div class="d-flex">
<span>{{ item.name }}</span>
<small class="statistics-percent" v-if="item.percent >= 0">{{ formatPercent(item.percent, 2, '&lt;0.01') }}</small>
<small class="statistics-percent" v-if="item.percent >= 0">{{ formatPercentToLocalizedNumerals(item.percent, 2, '&lt;0.01') }}</small>
<v-spacer/>
<span class="statistics-amount">{{ getDisplayAmount(item.totalAmount, defaultCurrency) }}</span>
</div>
@@ -374,9 +374,6 @@ import {
isNumber,
arrayItemToObjectField
} from '@/lib/common.ts';
import {
formatAmount
} from '@/lib/numeral.ts';
import {
getYearAndMonthFromUnixTime,
getYearMonthFirstUnixTime,
@@ -426,7 +423,14 @@ const props = defineProps<TransactionStatisticsProps>();
const router = useRouter();
const display = useDisplay();
const theme = useTheme();
const { tt, getAllCategoricalChartTypes, getAllTrendChartTypes, formatPercent } = useI18n();
const {
tt,
getAllCategoricalChartTypes,
getAllTrendChartTypes,
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
formatPercentToLocalizedNumerals
} = useI18n();
const {
loading,
@@ -956,7 +960,7 @@ function exportResults(): void {
.filter(item => !item.hidden)
.map(item => [
item.name,
formatAmount(item.totalAmount, {}),
formatAmountToWesternArabicNumeralsWithoutDigitGrouping(item.totalAmount),
item.percent.toFixed(4)
])
});
@@ -824,7 +824,7 @@
<v-btn color="teal" :disabled="submitting || !!editingTransaction || selectedImportTransactionCount < 1 || selectedInvalidTransactionCount > 0"
:append-icon="!submitting ? mdiArrowRight : undefined" @click="submit"
v-if="currentStep === 'checkData'">
{{ (submitting && importProcess > 0 ? tt('format.misc.importingTransactions', { process: formatNumber(importProcess, 2) }) : tt('Import')) }}
{{ (submitting && importProcess > 0 ? tt('format.misc.importingTransactions', { process: formatNumberToLocalizedNumerals(importProcess, 2) }) : tt('Import')) }}
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
</v-btn>
<v-btn color="secondary" variant="tonal"
@@ -998,8 +998,8 @@ const {
getAllImportTransactionColumnTypes,
getAllSupportedImportFileTypes,
formatUnixTimeToLongDateTime,
formatAmountWithCurrency,
formatNumber,
formatAmountToLocalizedNumeralsWithCurrency,
formatNumberToLocalizedNumerals,
getCategorizedAccountsWithDisplayBalance
} = useI18n();
@@ -1680,7 +1680,7 @@ function getDisplayTimezone(transaction: ImportTransaction): string {
}
function getDisplayCurrency(value: number, currencyCode: string): string {
return formatAmountWithCurrency(value, currencyCode);
return formatAmountToLocalizedNumeralsWithCurrency(value, currencyCode);
}
function getTransactionDisplayAmount(transaction: ImportTransaction): string {
@@ -243,6 +243,19 @@
/>
</v-col>
<v-col cols="12" md="6">
<v-select
item-title="displayName"
item-value="type"
persistent-placeholder
:disabled="loading || saving"
:label="tt('Numeral System')"
:placeholder="tt('Numeral System')"
:items="allNumeralSystemTypes"
v-model="newProfile.numeralSystem"
/>
</v-col>
<v-col cols="12" md="6">
<v-select
item-title="displayName"
@@ -401,10 +414,11 @@ const {
allLongTimeFormats,
allShortTimeFormats,
allFiscalYearFormats,
allCurrencyDisplayTypes,
allNumeralSystemTypes,
allDecimalSeparators,
allDigitGroupingSymbols,
allDigitGroupingTypes,
allCurrencyDisplayTypes,
allCoordinateDisplayTypes,
allExpenseAmountColorTypes,
allIncomeAmountColorTypes,