From 00b08a85ad65d5490a9088fd857eb6eb8affeaf9 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sun, 31 Jan 2021 00:25:01 +0800 Subject: [PATCH] transaction list page supports filtering by primary category --- pkg/api/transactions.go | 52 +++++++++++++++++++++--- pkg/services/transactions.go | 39 +++++++++++++----- src/views/mobile/transactions/List.vue | 55 +++++++++++++++++++++----- 3 files changed, 122 insertions(+), 24 deletions(-) diff --git a/pkg/api/transactions.go b/pkg/api/transactions.go index c747a829..45a9deaa 100644 --- a/pkg/api/transactions.go +++ b/pkg/api/transactions.go @@ -13,15 +13,17 @@ import ( // TransactionsApi represents transaction api type TransactionsApi struct { - transactions *services.TransactionService - transactionTags *services.TransactionTagService + transactions *services.TransactionService + transactionCategories *services.TransactionCategoryService + transactionTags *services.TransactionTagService } // Initialize a transaction api singleton instance var ( Transactions = &TransactionsApi{ - transactions: services.Transactions, - transactionTags: services.TransactionTags, + transactions: services.Transactions, + transactionCategories: services.TransactionCategories, + transactionTags: services.TransactionTags, } ) @@ -36,7 +38,26 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{}, } uid := c.GetCurrentUid() - transactions, err := a.transactions.GetTransactionsByMaxTime(uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, transactionListReq.CategoryId, transactionListReq.AccountId, transactionListReq.Keyword, transactionListReq.Count+1, true) + var allCategoryIds []int64 + + if transactionListReq.CategoryId > 0 { + allSubCategories, err := a.transactionCategories.GetAllCategoriesByUid(uid, 0, transactionListReq.CategoryId) + + if err != nil { + log.WarnfWithRequestId(c, "[transactions.TransactionListHandler] get transaction category error, because %s", err.Error()) + return nil, errs.ErrOperationFailed + } + + if len(allSubCategories) > 0 { + for i := 0; i < len(allSubCategories); i++ { + allCategoryIds = append(allCategoryIds, allSubCategories[i].CategoryId) + } + } else { + allCategoryIds = append(allCategoryIds, transactionListReq.CategoryId) + } + } + + transactions, err := a.transactions.GetTransactionsByMaxTime(uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, transactionListReq.AccountId, transactionListReq.Keyword, transactionListReq.Count+1, true) if err != nil { log.ErrorfWithRequestId(c, "[transactions.TransactionListHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", transactionListReq.MaxTime, uid, err.Error()) @@ -108,7 +129,26 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (interfac } uid := c.GetCurrentUid() - transactions, err := a.transactions.GetTransactionsInMonthByPage(uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, transactionListReq.CategoryId, transactionListReq.AccountId, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count) + var allCategoryIds []int64 + + if transactionListReq.CategoryId > 0 { + allSubCategories, err := a.transactionCategories.GetAllCategoriesByUid(uid, 0, transactionListReq.CategoryId) + + if err != nil { + log.WarnfWithRequestId(c, "[transactions.TransactionMonthListHandler] get transaction category error, because %s", err.Error()) + return nil, errs.ErrOperationFailed + } + + if len(allSubCategories) > 0 { + for i := 0; i < len(allSubCategories); i++ { + allCategoryIds = append(allCategoryIds, allSubCategories[i].CategoryId) + } + } else { + allCategoryIds = append(allCategoryIds, transactionListReq.CategoryId) + } + } + + transactions, err := a.transactions.GetTransactionsInMonthByPage(uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, transactionListReq.AccountId, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count) if err != nil { log.ErrorfWithRequestId(c, "[transactions.TransactionMonthListHandler] failed to get transactions in month \"%d-%d\" for user \"uid:%d\", because %s", transactionListReq.Year, transactionListReq.Month, uid, err.Error()) diff --git a/pkg/services/transactions.go b/pkg/services/transactions.go index 083b7ae0..bafa722f 100644 --- a/pkg/services/transactions.go +++ b/pkg/services/transactions.go @@ -2,6 +2,7 @@ package services import ( "fmt" + "strings" "time" "xorm.io/xorm" @@ -33,11 +34,11 @@ var ( // GetAllTransactionsByMaxTime returns all transactions before given time func (s *TransactionService) GetAllTransactionsByMaxTime(uid int64, maxTime int64, count int, noDuplicated bool) ([]*models.Transaction, error) { - return s.GetTransactionsByMaxTime(uid, maxTime, 0, 0, 0, 0, "", count, noDuplicated) + return s.GetTransactionsByMaxTime(uid, maxTime, 0, 0, nil, 0, "", count, noDuplicated) } // GetTransactionsByMaxTime returns transactions before given time -func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64, minTime int64, transactionType models.TransactionDbType, categoryId int64, accountId int64, keyword string, count int, noDuplicated bool) ([]*models.Transaction, error) { +func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64, minTime int64, transactionType models.TransactionDbType, categoryIds []int64, accountId int64, keyword string, count int, noDuplicated bool) ([]*models.Transaction, error) { if uid <= 0 { return nil, errs.ErrUserIdInvalid } @@ -76,9 +77,19 @@ func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64, } } - if categoryId > 0 { - condition = condition + " AND category_id=?" - conditionParams = append(conditionParams, categoryId) + if len(categoryIds) > 0 { + var conditions strings.Builder + + for i := 0; i < len(categoryIds); i++ { + if i > 0 { + conditions.WriteString(",") + } + + conditions.WriteString("?") + conditionParams = append(conditionParams, categoryIds[i]) + } + + condition = condition + " AND category_id IN (" + conditions.String() + ")" } if accountId > 0 { @@ -107,7 +118,7 @@ func (s *TransactionService) GetTransactionsByMaxTime(uid int64, maxTime int64, } // GetTransactionsInMonthByPage returns transactions in given year and month -func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, month int, transactionType models.TransactionDbType, categoryId int64, accountId int64, keyword string, page int, count int) ([]*models.Transaction, error) { +func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, month int, transactionType models.TransactionDbType, categoryIds []int64, accountId int64, keyword string, page int, count int) ([]*models.Transaction, error) { if uid <= 0 { return nil, errs.ErrUserIdInvalid } @@ -162,9 +173,19 @@ func (s *TransactionService) GetTransactionsInMonthByPage(uid int64, year int, m } } - if categoryId > 0 { - condition = condition + " AND category_id=?" - conditionParams = append(conditionParams, categoryId) + if len(categoryIds) > 0 { + var conditions strings.Builder + + for i := 0; i < len(categoryIds); i++ { + if i > 0 { + conditions.WriteString(",") + } + + conditions.WriteString("?") + conditionParams = append(conditionParams, categoryIds[i]) + } + + condition = condition + " AND category_id IN (" + conditions.String() + ")" } if accountId > 0 { diff --git a/src/views/mobile/transactions/List.vue b/src/views/mobile/transactions/List.vue index 3718f3e2..dfeea367 100644 --- a/src/views/mobile/transactions/List.vue +++ b/src/views/mobile/transactions/List.vue @@ -277,26 +277,44 @@ - + - - - + + + + + + + + + + + + + + @@ -388,6 +406,25 @@ export default { allCategories() { return this.$store.state.allTransactionCategoriesMap; }, + allPrimaryCategories() { + const primaryCategories = []; + + for (let categoryId in this.$store.state.allTransactionCategoriesMap) { + if (!Object.prototype.hasOwnProperty.call(this.$store.state.allTransactionCategoriesMap, categoryId)) { + continue; + } + + const category = this.$store.state.allTransactionCategoriesMap[categoryId]; + + if (category.parentId !== '0') { + continue; + } + + primaryCategories.push(category); + } + + return primaryCategories; + }, allDateRanges() { return this.$constants.datetime.allDateRanges; }