From bff6ca7e9dc668330702c1d91737a5904c17a18d Mon Sep 17 00:00:00 2001 From: MaysWind Date: Mon, 11 Nov 2024 01:27:44 +0800 Subject: [PATCH] support setting the time of the initial balance when creating a new account --- pkg/api/accounts.go | 12 +-- pkg/models/account.go | 1 + pkg/services/accounts.go | 12 ++- src/lib/account.js | 1 + src/lib/services.js | 3 +- src/locales/en.json | 3 + src/locales/zh_Hans.json | 3 + src/stores/account.js | 9 ++ .../accounts/list/dialogs/EditDialog.vue | 14 +++- src/views/mobile/accounts/EditPage.vue | 82 +++++++++++++++++++ 10 files changed, 130 insertions(+), 10 deletions(-) diff --git a/pkg/api/accounts.go b/pkg/api/accounts.go index 1624dd02..09ee69b4 100644 --- a/pkg/api/accounts.go +++ b/pkg/api/accounts.go @@ -217,7 +217,7 @@ func (a *AccountsApi) AccountCreateHandler(c *core.WebContext) (any, *errs.Error } mainAccount := a.createNewAccountModel(uid, &accountCreateReq, maxOrderId+1) - childrenAccounts := a.createSubAccountModels(uid, &accountCreateReq) + childrenAccounts, childrenAccountBalanceTimes := a.createSubAccountModels(uid, &accountCreateReq) if a.CurrentConfig().EnableDuplicateSubmissionsCheck && accountCreateReq.ClientSessionId != "" { found, remark := a.GetSubmissionRemark(duplicatechecker.DUPLICATE_CHECKER_TYPE_NEW_ACCOUNT, uid, accountCreateReq.ClientSessionId) @@ -255,7 +255,7 @@ func (a *AccountsApi) AccountCreateHandler(c *core.WebContext) (any, *errs.Error } } - err = a.accounts.CreateAccounts(c, mainAccount, childrenAccounts, utcOffset) + err = a.accounts.CreateAccounts(c, mainAccount, accountCreateReq.BalanceTime, childrenAccounts, childrenAccountBalanceTimes, utcOffset) if err != nil { log.Errorf(c, "[accounts.AccountCreateHandler] failed to create account \"id:%d\" for user \"uid:%d\", because %s", mainAccount.AccountId, uid, err.Error()) @@ -483,18 +483,20 @@ func (a *AccountsApi) createNewAccountModel(uid int64, accountCreateReq *models. } } -func (a *AccountsApi) createSubAccountModels(uid int64, accountCreateReq *models.AccountCreateRequest) []*models.Account { +func (a *AccountsApi) createSubAccountModels(uid int64, accountCreateReq *models.AccountCreateRequest) ([]*models.Account, []int64) { if len(accountCreateReq.SubAccounts) <= 0 { - return nil + return nil, nil } childrenAccounts := make([]*models.Account, len(accountCreateReq.SubAccounts)) + childrenAccountBalanceTimes := make([]int64, len(accountCreateReq.SubAccounts)) for i := int32(0); i < int32(len(accountCreateReq.SubAccounts)); i++ { childrenAccounts[i] = a.createNewAccountModel(uid, accountCreateReq.SubAccounts[i], i+1) + childrenAccountBalanceTimes[i] = accountCreateReq.SubAccounts[i].BalanceTime } - return childrenAccounts + return childrenAccounts, childrenAccountBalanceTimes } func (a *AccountsApi) getToUpdateAccount(uid int64, accountModifyReq *models.AccountModifyRequest, oldAccount *models.Account) *models.Account { diff --git a/pkg/models/account.go b/pkg/models/account.go index e883b3f8..6b5e244c 100644 --- a/pkg/models/account.go +++ b/pkg/models/account.go @@ -82,6 +82,7 @@ type AccountCreateRequest struct { Color string `json:"color" binding:"required,len=6,validHexRGBColor"` Currency string `json:"currency" binding:"required,len=3,validCurrency"` Balance int64 `json:"balance"` + BalanceTime int64 `json:"balanceTime" binding:"required,min=1"` Comment string `json:"comment" binding:"max=255"` SubAccounts []*AccountCreateRequest `json:"subAccounts" binding:"omitempty"` ClientSessionId string `json:"clientSessionId"` diff --git a/pkg/services/accounts.go b/pkg/services/accounts.go index d942b329..2fdb9890 100644 --- a/pkg/services/accounts.go +++ b/pkg/services/accounts.go @@ -195,7 +195,7 @@ func (s *AccountService) GetMaxSubAccountDisplayOrder(c core.Context, uid int64, } // CreateAccounts saves a new account model to database -func (s *AccountService) CreateAccounts(c core.Context, mainAccount *models.Account, childrenAccounts []*models.Account, utcOffset int16) error { +func (s *AccountService) CreateAccounts(c core.Context, mainAccount *models.Account, mainAccountBalanceTime int64, childrenAccounts []*models.Account, childrenAccountBalanceTimes []int64, utcOffset int16) error { if mainAccount.Uid <= 0 { return errs.ErrUserIdInvalid } @@ -230,8 +230,6 @@ func (s *AccountService) CreateAccounts(c core.Context, mainAccount *models.Acco } } - transactionTime := utils.GetMinTransactionTimeFromUnixTime(now) - for i := 0; i < len(allAccounts); i++ { allAccounts[i].Deleted = false allAccounts[i].CreatedUnixTime = now @@ -244,6 +242,14 @@ func (s *AccountService) CreateAccounts(c core.Context, mainAccount *models.Acco return errs.ErrSystemIsBusy } + transactionTime := utils.GetMinTransactionTimeFromUnixTime(now) + + if i == 0 && mainAccountBalanceTime > 0 { + transactionTime = utils.GetMinTransactionTimeFromUnixTime(mainAccountBalanceTime) + } else if i > 0 && len(childrenAccountBalanceTimes) > i-1 && childrenAccountBalanceTimes[i-1] > 0 { + transactionTime = utils.GetMinTransactionTimeFromUnixTime(childrenAccountBalanceTimes[i-1]) + } + newTransaction := &models.Transaction{ TransactionId: transactionId, Uid: allAccounts[i].Uid, diff --git a/src/lib/account.js b/src/lib/account.js index 8bb0036d..e9676c54 100644 --- a/src/lib/account.js +++ b/src/lib/account.js @@ -10,6 +10,7 @@ export function setAccountModelByAnotherAccount(account, account2) { account.color = account2.color; account.currency = account2.currency; account.balance = account2.balance; + account.balanceTime = account2.balanceTime; account.comment = account2.comment; account.visible = !account2.hidden; } diff --git a/src/lib/services.js b/src/lib/services.js index 55951199..38948270 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -255,7 +255,7 @@ export default { getAccount: ({ id }) => { return axios.get('v1/accounts/get.json?id=' + id); }, - addAccount: ({ category, type, name, icon, color, currency, balance, comment, subAccounts, clientSessionId }) => { + addAccount: ({ category, type, name, icon, color, currency, balance, balanceTime, comment, subAccounts, clientSessionId }) => { return axios.post('v1/accounts/add.json', { category, type, @@ -264,6 +264,7 @@ export default { color, currency, balance, + balanceTime, comment, subAccounts, clientSessionId diff --git a/src/locales/en.json b/src/locales/en.json index 08a3d071..acb11f0f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1172,6 +1172,7 @@ "parentId": "Parent Node ID", "categoryId": "Category ID", "time": "Time", + "balanceTime": "Balance Time", "startTime": "Start Time", "endTime": "End Time", "amountFilter": "Amount Filter", @@ -1461,6 +1462,8 @@ "Currency": "Currency", "Account Balance": "Account Balance", "Sub-account Balance": "Sub-account Balance", + "Balance Time": "Balance Time", + "Sub-account Balance Time": "Sub-account Balance Time", "Description": "Description", "Your account description (optional)": "Your account description (optional)", "Your sub-account description (optional)": "Your sub-account description (optional)", diff --git a/src/locales/zh_Hans.json b/src/locales/zh_Hans.json index c3c066ab..114bf83c 100644 --- a/src/locales/zh_Hans.json +++ b/src/locales/zh_Hans.json @@ -1172,6 +1172,7 @@ "parentId": "父节点ID", "categoryId": "分类ID", "time": "时间", + "balanceTime": "余额时间", "startTime": "开始时间", "endTime": "结束时间", "amountFilter": "金额过滤", @@ -1461,6 +1462,8 @@ "Currency": "货币", "Account Balance": "账户余额", "Sub-account Balance": "子账户余额", + "Balance Time": "余额时间", + "Sub-account Balance Time": "子账户余额时间", "Description": "描述", "Your account description (optional)": "你的账户描述 (可选)", "Your sub-account description (optional)": "你的子账户描述 (可选)", diff --git a/src/stores/account.js b/src/stores/account.js index b8bfb40e..974ddb0e 100644 --- a/src/stores/account.js +++ b/src/stores/account.js @@ -10,6 +10,7 @@ import colorConstants from '@/consts/color.js'; import services from '@/lib/services.js'; import logger from '@/lib/logger.js'; import { isNumber, isEquals } from '@/lib/common.js'; +import { getCurrentUnixTime } from '@/lib/datetime.js'; import { getCategorizedAccountsMap, getAllFilteredAccountsBalance } from '@/lib/account.js'; function loadAccountList(state, accounts) { @@ -254,6 +255,7 @@ export const useAccountsStore = defineStore('accounts', { actions: { generateNewAccountModel() { const userStore = useUserStore(); + const now = getCurrentUnixTime(); return { category: 1, @@ -263,12 +265,14 @@ export const useAccountsStore = defineStore('accounts', { color: colorConstants.defaultAccountColor, currency: userStore.currentUserDefaultCurrency, balance: 0, + balanceTime: now, comment: '', visible: true }; }, generateNewSubAccountModel(parentAccount) { const userStore = useUserStore(); + const now = getCurrentUnixTime(); return { category: null, @@ -278,6 +282,7 @@ export const useAccountsStore = defineStore('accounts', { color: parentAccount.color, currency: userStore.currentUserDefaultCurrency, balance: 0, + balanceTime: now, comment: '', visible: true }; @@ -758,6 +763,8 @@ export const useAccountsStore = defineStore('accounts', { if (isEdit) { submitAccount.id = subAccount.id; submitAccount.hidden = !subAccount.visible; + } else { + submitAccount.balanceTime = subAccount.balanceTime; } submitSubAccounts.push(submitAccount); @@ -783,6 +790,8 @@ export const useAccountsStore = defineStore('accounts', { if (isEdit) { submitAccount.id = account.id; submitAccount.hidden = !account.visible; + } else { + submitAccount.balanceTime = account.balanceTime; } const oldAccount = submitAccount.id ? self.allAccountsMap[submitAccount.id] : null; diff --git a/src/views/desktop/accounts/list/dialogs/EditDialog.vue b/src/views/desktop/accounts/list/dialogs/EditDialog.vue index 28aacffd..ff08fd51 100644 --- a/src/views/desktop/accounts/list/dialogs/EditDialog.vue +++ b/src/views/desktop/accounts/list/dialogs/EditDialog.vue @@ -126,7 +126,8 @@ - + + + + + + @@ -381,6 +401,26 @@ > + + @@ -433,6 +473,11 @@ import { setAccountModelByAnotherAccount, setAccountSuitableIcon } from '@/lib/account.js'; +import { + getTimezoneOffsetMinutes, + getBrowserTimezoneOffsetMinutes, + getActualUnixTimeForStore +} from '@/lib/datetime.js'; export default { props: [ @@ -445,6 +490,8 @@ export default { newAccount.showIconSelectionSheet = false; newAccount.showColorSelectionSheet = false; newAccount.showBalanceSheet = false; + newAccount.showBalanceDateTimeSheet = false; + newAccount.balanceDateTimeSheetMode = 'time'; return { editAccountId: null, @@ -534,6 +581,8 @@ export default { subAccount.showIconSelectionSheet = false; subAccount.showColorSelectionSheet = false; subAccount.showBalanceSheet = false; + subAccount.showBalanceDateTimeSheet = false; + subAccount.balanceDateTimeSheetMode = 'time'; self.subAccounts.push(subAccount); } @@ -566,6 +615,8 @@ export default { subAccount.showIconSelectionSheet = false; subAccount.showColorSelectionSheet = false; subAccount.showBalanceSheet = false; + subAccount.showBalanceDateTimeSheet = false; + subAccount.balanceDateTimeSheetMode = 'time'; this.subAccounts.push(subAccount); }, @@ -639,6 +690,10 @@ export default { } }); }, + showDateTimeDialog(account, sheetMode) { + account.balanceDateTimeSheetMode = sheetMode; + account.showBalanceDateTimeSheet = true; + }, getCurrencyName(currencyCode) { return this.$locale.getCurrencyName(currencyCode); }, @@ -651,6 +706,12 @@ export default { getAccountBalance(account) { return this.getDisplayCurrency(account.balance, account.currency); }, + getAccountBalanceDate(balanceTime) { + return this.$locale.formatUnixTimeToLongDate(this.userStore, getActualUnixTimeForStore(balanceTime, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())); + }, + getAccountBalanceTime(balanceTime) { + return this.$locale.formatUnixTimeToLongTime(this.userStore, getActualUnixTimeForStore(balanceTime, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())); + }, getDisplayCurrency(value, currencyCode) { return this.$locale.formatAmountWithCurrency(this.settingsStore, this.userStore, value, currencyCode); }, @@ -694,6 +755,27 @@ export default {