From 3b0ef7a96d141271a58d26d07fd4cef04ff1e89a Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sun, 2 Apr 2023 19:13:33 +0800 Subject: [PATCH] data management page shows all user data statistics --- cmd/webserver.go | 1 + pkg/api/data_managements.go | 41 ++++++++++++++++++++ pkg/models/data_management.go | 8 ++++ pkg/services/accounts.go | 11 ++++++ pkg/services/transaction_categories.go | 11 ++++++ pkg/services/transaction_tags.go | 11 ++++++ pkg/services/transactions.go | 11 ++++++ src/lib/services.js | 3 ++ src/locales/en.js | 2 + src/locales/zh_Hans.js | 2 + src/store/index.js | 2 + src/store/user.js | 25 ++++++++++++ src/views/mobile/users/DataManagement.vue | 47 ++++++++++++++++++++++- 13 files changed, 174 insertions(+), 1 deletion(-) diff --git a/cmd/webserver.go b/cmd/webserver.go index 53ac9f2d..1445d349 100644 --- a/cmd/webserver.go +++ b/cmd/webserver.go @@ -187,6 +187,7 @@ func startWebServer(c *cli.Context) error { } // Data + apiV1Route.GET("/data/statistics.json", bindApi(api.DataManagements.DataStatisticsHandler)) apiV1Route.POST("/data/clear.json", bindApi(api.DataManagements.ClearDataHandler)) // Accounts diff --git a/pkg/api/data_managements.go b/pkg/api/data_managements.go index 13f81030..f333a301 100644 --- a/pkg/api/data_managements.go +++ b/pkg/api/data_managements.go @@ -118,6 +118,47 @@ func (a *DataManagementsApi) ExportDataHandler(c *core.Context) ([]byte, string, return result, fileName, nil } +// DataStatisticsHandler returns user data statistics +func (a *DataManagementsApi) DataStatisticsHandler(c *core.Context) (interface{}, *errs.Error) { + uid := c.GetCurrentUid() + totalAccountCount, err := a.accounts.GetTotalAccountCountByUid(uid) + + if err != nil { + log.ErrorfWithRequestId(c, "[data_managements.DataStatisticsHandler] failed to get total account count for user \"uid:%d\", because %s", uid, err.Error()) + return nil, errs.ErrOperationFailed + } + + totalTransactionCategoryCount, err := a.categories.GetTotalCategoryCountByUid(uid) + + if err != nil { + log.ErrorfWithRequestId(c, "[data_managements.DataStatisticsHandler] failed to get total transaction category count for user \"uid:%d\", because %s", uid, err.Error()) + return nil, errs.ErrOperationFailed + } + + totalTransactionTagCount, err := a.tags.GetTotalTagCountByUid(uid) + + if err != nil { + log.ErrorfWithRequestId(c, "[data_managements.DataStatisticsHandler] failed to get total transaction tag count for user \"uid:%d\", because %s", uid, err.Error()) + return nil, errs.ErrOperationFailed + } + + totalTransactionCount, err := a.transactions.GetTotalTransactionCountByUid(uid) + + if err != nil { + log.ErrorfWithRequestId(c, "[data_managements.DataStatisticsHandler] failed to get total transaction count for user \"uid:%d\", because %s", uid, err.Error()) + return nil, errs.ErrOperationFailed + } + + dataStatisticsResp := &models.DataStatisticsResponse{ + TotalAccountCount: totalAccountCount, + TotalTransactionCategoryCount: totalTransactionCategoryCount, + TotalTransactionTagCount: totalTransactionTagCount, + TotalTransactionCount: totalTransactionCount, + } + + return dataStatisticsResp, nil +} + // ClearDataHandler deletes all user data func (a *DataManagementsApi) ClearDataHandler(c *core.Context) (interface{}, *errs.Error) { var clearDataReq models.ClearDataRequest diff --git a/pkg/models/data_management.go b/pkg/models/data_management.go index 3e61c11a..32948117 100644 --- a/pkg/models/data_management.go +++ b/pkg/models/data_management.go @@ -4,3 +4,11 @@ package models type ClearDataRequest struct { Password string `json:"password" binding:"omitempty,min=6,max=128"` } + +// DataStatisticsResponse represents a view-object of user data statistic +type DataStatisticsResponse struct { + TotalAccountCount int64 `json:"totalAccountCount,string"` + TotalTransactionCategoryCount int64 `json:"totalTransactionCategoryCount,string"` + TotalTransactionTagCount int64 `json:"totalTransactionTagCount,string"` + TotalTransactionCount int64 `json:"totalTransactionCount,string"` +} diff --git a/pkg/services/accounts.go b/pkg/services/accounts.go index 1adbedc6..79e7208f 100644 --- a/pkg/services/accounts.go +++ b/pkg/services/accounts.go @@ -30,6 +30,17 @@ var ( } ) +// GetTotalAccountCountByUid returns total account count of user +func (s *AccountService) GetTotalAccountCountByUid(uid int64) (int64, error) { + if uid <= 0 { + return 0, errs.ErrUserIdInvalid + } + + count, err := s.UserDataDB(uid).Where("uid=? AND deleted=?", uid, false).Count(&models.Account{}) + + return count, err +} + // GetAllAccountsByUid returns all account models of user func (s *AccountService) GetAllAccountsByUid(uid int64) ([]*models.Account, error) { if uid <= 0 { diff --git a/pkg/services/transaction_categories.go b/pkg/services/transaction_categories.go index 75764adc..36204f75 100644 --- a/pkg/services/transaction_categories.go +++ b/pkg/services/transaction_categories.go @@ -29,6 +29,17 @@ var ( } ) +// GetTotalCategoryCountByUid returns total category count of user +func (s *TransactionCategoryService) GetTotalCategoryCountByUid(uid int64) (int64, error) { + if uid <= 0 { + return 0, errs.ErrUserIdInvalid + } + + count, err := s.UserDataDB(uid).Where("uid=? AND deleted=?", uid, false).Count(&models.TransactionCategory{}) + + return count, err +} + // GetAllCategoriesByUid returns all transaction category models of user func (s *TransactionCategoryService) GetAllCategoriesByUid(uid int64, categoryType models.TransactionCategoryType, parentCategoryId int64) ([]*models.TransactionCategory, error) { if uid <= 0 { diff --git a/pkg/services/transaction_tags.go b/pkg/services/transaction_tags.go index cbfcda56..777fc1df 100644 --- a/pkg/services/transaction_tags.go +++ b/pkg/services/transaction_tags.go @@ -29,6 +29,17 @@ var ( } ) +// GetTotalTagCountByUid returns total tag count of user +func (s *TransactionTagService) GetTotalTagCountByUid(uid int64) (int64, error) { + if uid <= 0 { + return 0, errs.ErrUserIdInvalid + } + + count, err := s.UserDataDB(uid).Where("uid=? AND deleted=?", uid, false).Count(&models.TransactionTag{}) + + return count, err +} + // GetAllTagsByUid returns all transaction tag models of user func (s *TransactionTagService) GetAllTagsByUid(uid int64) ([]*models.TransactionTag, error) { if uid <= 0 { diff --git a/pkg/services/transactions.go b/pkg/services/transactions.go index 80bcdd35..58031ac1 100644 --- a/pkg/services/transactions.go +++ b/pkg/services/transactions.go @@ -32,6 +32,17 @@ var ( } ) +// GetTotalTransactionCountByUid returns total transaction count of user +func (s *TransactionService) GetTotalTransactionCountByUid(uid int64) (int64, error) { + if uid <= 0 { + return 0, errs.ErrUserIdInvalid + } + + count, err := s.UserDataDB(uid).Where("uid=? AND deleted=?", uid, false).Count(&models.Transaction{}) + + return count, err +} + // GetAllTransactions returns all transactions func (s *TransactionService) GetAllTransactions(uid int64, pageCount int32, noDuplicated bool) ([]*models.Transaction, error) { maxTransactionTime := utils.GetMaxTransactionTimeFromUnixTime(time.Now().Unix()) diff --git a/src/lib/services.js b/src/lib/services.js index dd61868d..6c7a8288 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -167,6 +167,9 @@ export default { password }); }, + getUserDataStatistics: () => { + return axios.get('v1/data/statistics.json'); + }, clearData: ({ password }) => { return axios.post('v1/data/clear.json', { password diff --git a/src/locales/en.js b/src/locales/en.js index 6d8934e3..b69886d8 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -811,6 +811,7 @@ export default { 'Are you sure you want to delete this account?': 'Are you sure you want to delete this account?', 'Unable to delete this account': 'Unable to delete this account', 'Transaction': 'Transaction', + 'Transactions': 'Transactions', 'Add Transaction': 'Add Transaction', 'Edit Transaction': 'Edit Transaction', 'Modify Balance': 'Modify Balance', @@ -897,6 +898,7 @@ export default { 'Your profile has been successfully updated': 'Your profile has been successfully updated', 'Unable to update user profile': 'Unable to update user profile', 'Data Management': 'Data Management', + 'Unable to get user statistics data': 'Unable to get user statistics data', 'Export Data': 'Export Data', 'Clear User Data': 'Clear User Data', 'Are you sure you want to clear all data?': 'Are you sure you want to clear all data?', diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js index a471bcc6..3e57bfad 100644 --- a/src/locales/zh_Hans.js +++ b/src/locales/zh_Hans.js @@ -811,6 +811,7 @@ export default { 'Are you sure you want to delete this account?': '您确定要删除该账户?', 'Unable to delete this account': '无法删除该账户', 'Transaction': '交易', + 'Transactions': '交易', 'Add Transaction': '添加交易', 'Edit Transaction': '编辑交易', 'Modify Balance': '修改余额', @@ -897,6 +898,7 @@ export default { 'Your profile has been successfully updated': '您的用户信息更新成功', 'Unable to update user profile': '无法更新用户信息', 'Data Management': '数据管理', + 'Unable to get user statistics data': '无法获取用户统计数据', 'Export Data': '导出数据', 'Clear User Data': '清除用户数据', 'Are you sure you want to clear all data?': '您确定要清除所有数据?', diff --git a/src/store/index.js b/src/store/index.js index 787a6085..084c5511 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -67,6 +67,7 @@ import { logout, getCurrentUserProfile, updateUserProfile, + getUserDataStatistics, clearUserData, clearUserInfoState, resetState, @@ -945,6 +946,7 @@ const stores = { logout, getCurrentUserProfile, updateUserProfile, + getUserDataStatistics, clearUserData, clearUserInfoState, resetState, diff --git a/src/store/user.js b/src/store/user.js index 488089e1..310f2390 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -282,6 +282,31 @@ export function updateUserProfile(context, { profile, currentPassword }) { }); } +export function getUserDataStatistics() { + return new Promise((resolve, reject) => { + services.getUserDataStatistics().then(response => { + const data = response.data; + + if (!data || !data.success || !data.result) { + reject({ message: 'Unable to get user statistics data' }); + return; + } + + resolve(data.result); + }).catch(error => { + logger.error('failed to get user statistics data', error); + + if (error.response && error.response.data && error.response.data.errorMessage) { + reject({ error: error.response.data }); + } else if (!error.processed) { + reject({ message: 'Unable to get user statistics data' }); + } else { + reject(error); + } + }); + }); +} + export function clearUserData(context, { password }) { return new Promise((resolve, reject) => { services.clearData({ diff --git a/src/views/mobile/users/DataManagement.vue b/src/views/mobile/users/DataManagement.vue index 5c5b7d12..127972ca 100644 --- a/src/views/mobile/users/DataManagement.vue +++ b/src/views/mobile/users/DataManagement.vue @@ -1,7 +1,29 @@