From 0b3260778b775a1d0bb823c16a7c9209484dca02 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Fri, 5 Jul 2024 00:32:04 +0800 Subject: [PATCH] code refactor --- src/lib/account.js | 32 +++++ src/locales/en.js | 2 + src/locales/zh_Hans.js | 2 + src/stores/transaction.js | 146 ++++++++++++++------ src/views/desktop/transactions/ListPage.vue | 126 ++++++++++------- src/views/mobile/transactions/ListPage.vue | 114 +++++++++------ 6 files changed, 284 insertions(+), 138 deletions(-) diff --git a/src/lib/account.js b/src/lib/account.js index 9deeae39..b8c6d32d 100644 --- a/src/lib/account.js +++ b/src/lib/account.js @@ -1,3 +1,4 @@ +import currencyConstants from '@/consts/currency.js'; import accountConstants from '@/consts/account.js'; export function setAccountModelByAnotherAccount(account, account2) { @@ -227,6 +228,37 @@ export function getAllFilteredAccountsBalance(categorizedAccounts, accountFilter return ret; } +export function getUnifiedSelectedAccountsCurrencyOrDefaultCurrency(allAccounts, selectedAccountIds, defaultCurrency) { + if (!selectedAccountIds) { + return defaultCurrency; + } + + let accountCurrency = ''; + + for (let accountId in selectedAccountIds) { + if (!Object.prototype.hasOwnProperty.call(selectedAccountIds, accountId)) { + continue; + } + + const account = allAccounts[accountId]; + + if (account.currency === currencyConstants.parentAccountCurrencyPlaceholder) { + continue; + } + + if (accountCurrency === '') { + accountCurrency = account.currency; + } else if (accountCurrency !== account.currency) { + return defaultCurrency; + } + } + + if (accountCurrency) { + return accountCurrency; + } + + return defaultCurrency; +} export function selectAccountOrSubAccounts(filterAccountIds, account, value) { if (account.type === accountConstants.allAccountTypes.SingleAccount) { diff --git a/src/locales/en.js b/src/locales/en.js index bc7c8350..ff973465 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -1009,7 +1009,9 @@ export default { 'Swap Amount': 'Swap Amount', 'Swap Account and Amount': 'Swap Account and Amount', 'Category': 'Category', + 'Multiple Categories': 'Multiple Categories', 'Account': 'Account', + 'Multiple Accounts': 'Multiple Accounts', 'Source Account': 'Source Account', 'Destination Account': 'Destination Account', 'Transaction Time': 'Transaction Time', diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js index a8ee9e05..aaf34317 100644 --- a/src/locales/zh_Hans.js +++ b/src/locales/zh_Hans.js @@ -1009,7 +1009,9 @@ export default { 'Swap Amount': '交换金额', 'Swap Account and Amount': '交换账户和金额', 'Category': '分类', + 'Multiple Categories': '多个分类', 'Account': '账户', + 'Multiple Accounts': '多个账户', 'Source Account': '来源账户', 'Destination Account': '目标账户', 'Transaction Time': '交易时间', diff --git a/src/stores/transaction.js b/src/stores/transaction.js index 64cd6da0..987d5b38 100644 --- a/src/stores/transaction.js +++ b/src/stores/transaction.js @@ -64,7 +64,7 @@ function loadTransactionList(state, settingsStore, exchangeRatesStore, { transac } if (!currentMonthList || currentMonthList.year !== transactionYear || currentMonthList.month !== transactionMonth) { - calculateMonthTotalAmount(state, exchangeRatesStore, currentMonthList, defaultCurrency, state.transactionsFilter.accountId, false); + calculateMonthTotalAmount(state, exchangeRatesStore, currentMonthList, defaultCurrency, state.transactionsFilter.accountIds, false); state.transactions.push({ year: transactionYear, @@ -79,14 +79,14 @@ function loadTransactionList(state, settingsStore, exchangeRatesStore, { transac } currentMonthList.items.push(Object.freeze(item)); - calculateMonthTotalAmount(state, exchangeRatesStore, currentMonthList, defaultCurrency, state.transactionsFilter.accountId, true); + calculateMonthTotalAmount(state, exchangeRatesStore, currentMonthList, defaultCurrency, state.transactionsFilter.accountIds, true); } } if (transactions.nextTimeSequenceId) { state.transactionsNextTimeId = transactions.nextTimeSequenceId; } else { - calculateMonthTotalAmount(state, exchangeRatesStore, state.transactions[state.transactions.length - 1], defaultCurrency, state.transactionsFilter.accountId, false); + calculateMonthTotalAmount(state, exchangeRatesStore, state.transactions[state.transactions.length - 1], defaultCurrency, state.transactionsFilter.accountIds, false); state.transactionsNextTimeId = -1; } } @@ -115,12 +115,10 @@ function updateTransactionInTransactionList(state, settingsStore, exchangeRatesS return; } - if ((state.transactionsFilter.categoryId && state.transactionsFilter.categoryId !== '0' && state.transactionsFilter.categoryId !== transaction.categoryId) || - (state.transactionsFilter.accountId && state.transactionsFilter.accountId !== '0' && - state.transactionsFilter.accountId !== transaction.sourceAccountId && - state.transactionsFilter.accountId !== transaction.destinationAccountId && - (!transaction.sourceAccount || state.transactionsFilter.accountId !== transaction.sourceAccount.parentId) && - (!transaction.destinationAccount || state.transactionsFilter.accountId !== transaction.destinationAccount.parentId) + if ((state.transactionsFilter.categoryIds && !state.allFilterCategoryIds[transaction.categoryId]) || + (state.transactionsFilter.accountIds && !state.allFilterAccountIds[transaction.sourceAccountId] && !state.allFilterAccountIds[transaction.destinationAccountId] && + (!transaction.sourceAccount || !state.allFilterAccountIds[transaction.sourceAccount.parentId]) && + (!transaction.destinationAccount || !state.allFilterAccountIds[transaction.destinationAccount.parentId]) ) ) { transactionMonthList.items.splice(j, 1); @@ -131,7 +129,7 @@ function updateTransactionInTransactionList(state, settingsStore, exchangeRatesS if (transactionMonthList.items.length < 1) { state.transactions.splice(i, 1); } else { - calculateMonthTotalAmount(state, exchangeRatesStore, transactionMonthList, defaultCurrency, state.transactionsFilter.accountId, i >= state.transactions.length - 1 && state.transactionsNextTimeId > 0); + calculateMonthTotalAmount(state, exchangeRatesStore, transactionMonthList, defaultCurrency, state.transactionsFilter.accountIds, i >= state.transactions.length - 1 && state.transactionsNextTimeId > 0); } return; @@ -159,12 +157,12 @@ function removeTransactionFromTransactionList(state, exchangeRatesStore, { trans if (transactionMonthList.items.length < 1) { state.transactions.splice(i, 1); } else { - calculateMonthTotalAmount(state, exchangeRatesStore, transactionMonthList, defaultCurrency, state.transactionsFilter.accountId, i >= state.transactions.length - 1 && state.transactionsNextTimeId > 0); + calculateMonthTotalAmount(state, exchangeRatesStore, transactionMonthList, defaultCurrency, state.transactionsFilter.accountIds, i >= state.transactions.length - 1 && state.transactionsNextTimeId > 0); } } } -function calculateMonthTotalAmount(state, exchangeRatesStore, transactionMonthList, defaultCurrency, accountId, incomplete) { +function calculateMonthTotalAmount(state, exchangeRatesStore, transactionMonthList, defaultCurrency, accountIds, incomplete) { if (!transactionMonthList) { return; } @@ -180,7 +178,7 @@ function calculateMonthTotalAmount(state, exchangeRatesStore, transactionMonthLi let amount = transaction.sourceAmount; let account = transaction.sourceAccount; - if (accountId && transaction.destinationAccount && (transaction.destinationAccount.id === accountId || transaction.destinationAccount.parentId === accountId)) { + if (accountIds && transaction.destinationAccount && (transaction.destinationAccount.id === accountIds || transaction.destinationAccount.parentId === accountIds)) { amount = transaction.destinationAmount; account = transaction.destinationAccount; } @@ -209,17 +207,17 @@ function calculateMonthTotalAmount(state, exchangeRatesStore, transactionMonthLi totalExpense += amount; } else if (transaction.type === transactionConstants.allTransactionTypes.Income) { totalIncome += amount; - } else if (transaction.type === transactionConstants.allTransactionTypes.Transfer && accountId && accountId !== '0') { - if (accountId === transaction.sourceAccountId) { + } else if (transaction.type === transactionConstants.allTransactionTypes.Transfer && accountIds && accountIds !== '0') { + if (accountIds === transaction.sourceAccountId) { totalExpense += amount; - } else if (accountId === transaction.destinationAccountId) { + } else if (accountIds === transaction.destinationAccountId) { totalIncome += amount; - } else if (transaction.sourceAccount && accountId === transaction.sourceAccount.parentId && - transaction.destinationAccount && accountId === transaction.destinationAccount.parentId) { + } else if (transaction.sourceAccount && accountIds === transaction.sourceAccount.parentId && + transaction.destinationAccount && accountIds === transaction.destinationAccount.parentId) { // Do Nothing - } else if (transaction.sourceAccount && accountId === transaction.sourceAccount.parentId) { + } else if (transaction.sourceAccount && accountIds === transaction.sourceAccount.parentId) { totalExpense += amount; - } else if (transaction.destinationAccount && accountId === transaction.destinationAccount.parentId) { + } else if (transaction.destinationAccount && accountIds === transaction.destinationAccount.parentId) { totalIncome += amount; } } @@ -268,8 +266,8 @@ export const useTransactionsStore = defineStore('transactions', { maxTime: 0, minTime: 0, type: 0, - categoryId: '0', - accountId: '0', + categoryIds: '', + accountIds: '', amountFilter: '', keyword: '' }, @@ -278,6 +276,70 @@ export const useTransactionsStore = defineStore('transactions', { transactionListStateInvalid: true, }), getters: { + allFilterCategoryIds(state) { + if (!state.transactionsFilter.categoryIds) { + return {}; + } + + const allCategoryIds = state.transactionsFilter.categoryIds.split(','); + const ret = {}; + + for (let i = 0; i < allCategoryIds.length; i++) { + if (allCategoryIds[i]) { + ret[allCategoryIds[i]] = true; + } + } + + return ret; + }, + allFilterAccountIds(state) { + if (!state.transactionsFilter.accountIds) { + return {}; + } + + const allAccountIds = state.transactionsFilter.accountIds.split(','); + const ret = {}; + + for (let i = 0; i < allAccountIds.length; i++) { + if (allAccountIds[i]) { + ret[allAccountIds[i]] = true; + } + } + + return ret; + }, + allFilterCategoryIdsCount(state) { + if (!state.transactionsFilter.categoryIds) { + return 0; + } + + const allCategoryIds = state.transactionsFilter.categoryIds.split(','); + let count = 0; + + for (let i = 0; i < allCategoryIds.length; i++) { + if (allCategoryIds[i]) { + count++; + } + } + + return count; + }, + allFilterAccountIdsCount(state) { + if (!state.transactionsFilter.accountIds) { + return 0; + } + + const allAccountIds = state.transactionsFilter.accountIds.split(','); + let count = 0; + + for (let i = 0; i < allAccountIds.length; i++) { + if (allAccountIds[i]) { + count++; + } + } + + return count; + }, noTransaction(state) { for (let i = 0; i < state.transactions.length; i++) { const transactionMonthList = state.transactions[i]; @@ -364,8 +426,8 @@ export const useTransactionsStore = defineStore('transactions', { this.transactionsFilter.maxTime = 0; this.transactionsFilter.minTime = 0; this.transactionsFilter.type = 0; - this.transactionsFilter.categoryId = '0'; - this.transactionsFilter.accountId = '0'; + this.transactionsFilter.categoryIds = ''; + this.transactionsFilter.accountIds = ''; this.transactionsFilter.amountFilter = ''; this.transactionsFilter.keyword = ''; this.transactions = []; @@ -402,16 +464,16 @@ export const useTransactionsStore = defineStore('transactions', { this.transactionsFilter.type = 0; } - if (filter && isString(filter.categoryId)) { - this.transactionsFilter.categoryId = filter.categoryId; + if (filter && isString(filter.categoryIds)) { + this.transactionsFilter.categoryIds = filter.categoryIds; } else { - this.transactionsFilter.categoryId = '0'; + this.transactionsFilter.categoryIds = ''; } - if (filter && isString(filter.accountId)) { - this.transactionsFilter.accountId = filter.accountId; + if (filter && isString(filter.accountIds)) { + this.transactionsFilter.accountIds = filter.accountIds; } else { - this.transactionsFilter.accountId = '0'; + this.transactionsFilter.accountIds = ''; } if (filter && isString(filter.amountFilter)) { @@ -443,12 +505,12 @@ export const useTransactionsStore = defineStore('transactions', { this.transactionsFilter.type = filter.type; } - if (filter && isString(filter.categoryId)) { - this.transactionsFilter.categoryId = filter.categoryId; + if (filter && isString(filter.categoryIds)) { + this.transactionsFilter.categoryIds = filter.categoryIds; } - if (filter && isString(filter.accountId)) { - this.transactionsFilter.accountId = filter.accountId; + if (filter && isString(filter.accountIds)) { + this.transactionsFilter.accountIds = filter.accountIds; } if (filter && isString(filter.amountFilter)) { @@ -466,12 +528,12 @@ export const useTransactionsStore = defineStore('transactions', { querys.push('type=' + this.transactionsFilter.type); } - if (this.transactionsFilter.accountId && this.transactionsFilter.accountId !== '0') { - querys.push('accountIds=' + this.transactionsFilter.accountId); + if (this.transactionsFilter.accountIds) { + querys.push('accountIds=' + this.transactionsFilter.accountIds); } - if (this.transactionsFilter.categoryId && this.transactionsFilter.categoryId !== '0') { - querys.push('categoryIds=' + this.transactionsFilter.categoryId); + if (this.transactionsFilter.categoryIds) { + querys.push('categoryIds=' + this.transactionsFilter.categoryIds); } querys.push('dateType=' + this.transactionsFilter.dateType); @@ -511,8 +573,8 @@ export const useTransactionsStore = defineStore('transactions', { page: page || 1, withCount: (!!withCount) || false, type: self.transactionsFilter.type, - categoryIds: self.transactionsFilter.categoryId, - accountIds: self.transactionsFilter.accountId, + categoryIds: self.transactionsFilter.categoryIds, + accountIds: self.transactionsFilter.accountIds, amountFilter: self.transactionsFilter.amountFilter, keyword: self.transactionsFilter.keyword }).then(response => { @@ -586,8 +648,8 @@ export const useTransactionsStore = defineStore('transactions', { year: year, month: month, type: self.transactionsFilter.type, - categoryIds: self.transactionsFilter.categoryId, - accountIds: self.transactionsFilter.accountId, + categoryIds: self.transactionsFilter.categoryIds, + accountIds: self.transactionsFilter.accountIds, amountFilter: self.transactionsFilter.amountFilter, keyword: self.transactionsFilter.keyword }).then(response => { diff --git a/src/views/desktop/transactions/ListPage.vue b/src/views/desktop/transactions/ListPage.vue index d8a1db6c..4b3f6330 100644 --- a/src/views/desktop/transactions/ListPage.vue +++ b/src/views/desktop/transactions/ListPage.vue @@ -116,17 +116,17 @@ @update:model-value="scrollCategoryMenuToSelectedItem"> - - + + + @click="changeCategoryFilter('')">
{{ $t('All') }} @@ -146,7 +146,7 @@ @@ -346,16 +346,16 @@ v-model:opened="showAccountPopover" @popover:open="scrollPopoverToSelectedItem"> - + + v-if="query.accountIds === account.id"> @@ -461,6 +461,7 @@ import { getDateRangeByDateType } from '@/lib/datetime.js'; import { categoryTypeToTransactionType, transactionTypeToCategoryType } from '@/lib/category.js'; +import { getUnifiedSelectedAccountsCurrencyOrDefaultCurrency } from '@/lib/account.js'; import { onSwipeoutDeleted, scrollToSelectedItem } from '@/lib/ui.mobile.js'; export default { @@ -487,19 +488,15 @@ export default { computed: { ...mapStores(useSettingsStore, useUserStore, useAccountsStore, useTransactionCategoriesStore, useTransactionsStore), defaultCurrency() { - if (this.query.accountId && this.query.accountId !== '0') { - const account = this.allAccounts[this.query.accountId]; - - if (account && account.currency && account.currency !== currencyConstants.parentAccountCurrencyPlaceholder) { - return account.currency; - } - } - - return this.userStore.currentUserDefaultCurrency; + return getUnifiedSelectedAccountsCurrencyOrDefaultCurrency(this.allAccounts, this.queryAllFilterAccountIds, this.userStore.currentUserDefaultCurrency); }, canAddTransaction() { - if (this.query.accountId && this.query.accountId !== '0') { - const account = this.allAccounts[this.query.accountId]; + if (this.queryAllFilterCategoryIdsCount > 1 || this.queryAllFilterAccountIdsCount > 1) { + return false; + } + + if (this.query.accountIds) { + const account = this.allAccounts[this.query.accountIds]; if (account && account.type === accountConstants.allAccountTypes.MultiSubAccounts) { return false; @@ -530,11 +527,31 @@ export default { queryMaxTime() { return this.$locale.formatUnixTimeToLongDateTime(this.userStore, this.query.maxTime); }, + queryAllFilterCategoryIds() { + return this.transactionsStore.allFilterCategoryIds; + }, + queryAllFilterAccountIds() { + return this.transactionsStore.allFilterAccountIds; + }, + queryAllFilterCategoryIdsCount() { + return this.transactionsStore.allFilterCategoryIdsCount; + }, + queryAllFilterAccountIdsCount() { + return this.transactionsStore.allFilterAccountIdsCount; + }, queryCategoryName() { - return getNameByKeyValue(this.allCategories, this.query.categoryId, null, 'name', this.$t('Category')); + if (this.queryAllFilterCategoryIdsCount > 1) { + return this.$t('Multiple Categories'); + } + + return getNameByKeyValue(this.allCategories, this.query.categoryIds, null, 'name', this.$t('Category')); }, queryAccountName() { - return getNameByKeyValue(this.allAccounts, this.query.accountId, null, 'name', this.$t('Account')); + if (this.queryAllFilterAccountIdsCount > 1) { + return this.$t('Multiple Accounts'); + } + + return getNameByKeyValue(this.allAccounts, this.query.accountIds, null, 'name', this.$t('Account')); }, queryAmount() { if (!this.query.amountFilter) { @@ -628,8 +645,8 @@ export default { maxTime: dateRange ? dateRange.maxTime : undefined, minTime: dateRange ? dateRange.minTime : undefined, type: parseInt(query.type) > 0 ? parseInt(query.type) : undefined, - categoryId: query.categoryId, - accountId: query.accountId + categoryIds: query.categoryIds, + accountIds: query.accountIds }); this.reload(null); @@ -777,41 +794,48 @@ export default { let removeCategoryFilter = false; - if (type && this.query.categoryId) { - const category = this.allCategories[this.query.categoryId]; + if (type && this.query.categoryIds) { + for (let categoryId in this.queryAllFilterCategoryIds) { + if (!Object.prototype.hasOwnProperty.call(this.queryAllFilterCategoryIds, categoryId)) { + continue; + } + + const category = this.allCategories[categoryId]; - if (category && category.type !== transactionTypeToCategoryType(type)) { - removeCategoryFilter = true; + if (category && category.type !== transactionTypeToCategoryType(type)) { + removeCategoryFilter = true; + break; + } } } this.transactionsStore.updateTransactionListFilter({ type: type, - categoryId: removeCategoryFilter ? '0' : undefined + categoryIds: removeCategoryFilter ? '' : undefined }); this.showMorePopover = false; this.reload(null); }, - changeCategoryFilter(categoryId) { - if (this.query.categoryId === categoryId) { + changeCategoryFilter(categoryIds) { + if (this.query.categoryIds === categoryIds) { return; } this.transactionsStore.updateTransactionListFilter({ - categoryId: categoryId + categoryIds: categoryIds }); this.showCategoryPopover = false; this.reload(null); }, - changeAccountFilter(accountId) { - if (this.query.accountId === accountId) { + changeAccountFilter(accountIds) { + if (this.query.accountIds === accountIds) { return; } this.transactionsStore.updateTransactionListFilter({ - accountId: accountId + accountIds: accountIds }); this.showAccountPopover = false; @@ -959,15 +983,15 @@ export default { color: 'transparent' } }, - getCategoryListItemCheckedClass(category, queryCategoryId) { - if (category.id === queryCategoryId) { + getCategoryListItemCheckedClass(category, queryCategoryIds) { + if (queryCategoryIds && queryCategoryIds[category.id]) { return { 'list-item-checked': true }; } for (let i = 0; i < category.subCategories.length; i++) { - if (category.subCategories[i].id === queryCategoryId) { + if (queryCategoryIds && queryCategoryIds[category.subCategories[i].id]) { return { 'list-item-checked': true };