diff --git a/cmd/user_data.go b/cmd/user_data.go index 697e455b..dc157cab 100644 --- a/cmd/user_data.go +++ b/cmd/user_data.go @@ -399,6 +399,7 @@ func printUserInfo(user *models.User) { fmt.Printf("[Password] %s\n", user.Password) fmt.Printf("[Salt] %s\n", user.Salt) fmt.Printf("[DefaultCurrency] %s\n", user.DefaultCurrency) + fmt.Printf("[DefaultAccountId] %s\n", user.DefaultAccountId) fmt.Printf("[FirstDayOfWeek] %s\n", user.FirstDayOfWeek) fmt.Printf("[TransactionEditScope] %s\n", user.TransactionEditScope) fmt.Printf("[Deleted] %t\n", user.Deleted) diff --git a/pkg/api/users.go b/pkg/api/users.go index 44479cc7..5b47aa85 100644 --- a/pkg/api/users.go +++ b/pkg/api/users.go @@ -15,15 +15,17 @@ import ( // UsersApi represents user api type UsersApi struct { - users *services.UserService - tokens *services.TokenService + users *services.UserService + tokens *services.TokenService + accounts *services.AccountService } // Initialize a user api singleton instance var ( Users = &UsersApi{ - users: services.Users, - tokens: services.Tokens, + users: services.Users, + tokens: services.Tokens, + accounts: services.Accounts, } ) @@ -165,6 +167,18 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs anythingUpdate = true } + if userUpdateReq.DefaultAccountId > 0 && userUpdateReq.DefaultAccountId != user.DefaultAccountId { + accounts, err := a.accounts.GetAccountsByAccountIds(uid, []int64{userUpdateReq.DefaultAccountId}) + + if err != nil || len(accounts) < 1 { + return nil, errs.Or(err, errs.ErrUserDefaultAccountIsInvalid) + } + + user.DefaultAccountId = userUpdateReq.DefaultAccountId + userNew.DefaultAccountId = userUpdateReq.DefaultAccountId + anythingUpdate = true + } + if userUpdateReq.FirstDayOfWeek != nil && *userUpdateReq.FirstDayOfWeek != user.FirstDayOfWeek { user.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek userNew.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek diff --git a/pkg/errs/user.go b/pkg/errs/user.go index 8fd424f0..698461c7 100644 --- a/pkg/errs/user.go +++ b/pkg/errs/user.go @@ -21,4 +21,5 @@ var ( ErrUsernameAlreadyExists = NewNormalError(NormalSubcategoryUser, 12, http.StatusBadRequest, "username already exists") ErrUserEmailAlreadyExists = NewNormalError(NormalSubcategoryUser, 13, http.StatusBadRequest, "email already exists") ErrUserRegistrationNotAllowed = NewNormalError(NormalSubcategoryUser, 14, http.StatusBadRequest, "user registration not allowed") + ErrUserDefaultAccountIsInvalid = NewNormalError(NormalSubcategoryUser, 15, http.StatusBadRequest, "user default account is invalid") ) diff --git a/pkg/models/user.go b/pkg/models/user.go index 9bbf7f0f..5aaf428c 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -87,13 +87,14 @@ func (s TransactionEditScope) String() string { // User represents user data stored in database type User struct { - Uid int64 `xorm:"PK"` - Username string `xorm:"VARCHAR(32) UNIQUE NOT NULL"` - Email string `xorm:"VARCHAR(100) UNIQUE NOT NULL"` - Nickname string `xorm:"VARCHAR(64) NOT NULL"` - Password string `xorm:"VARCHAR(64) NOT NULL"` - Salt string `xorm:"VARCHAR(10) NOT NULL"` - DefaultCurrency string `xorm:"VARCHAR(3) NOT NULL"` + Uid int64 `xorm:"PK"` + Username string `xorm:"VARCHAR(32) UNIQUE NOT NULL"` + Email string `xorm:"VARCHAR(100) UNIQUE NOT NULL"` + Nickname string `xorm:"VARCHAR(64) NOT NULL"` + Password string `xorm:"VARCHAR(64) NOT NULL"` + Salt string `xorm:"VARCHAR(10) NOT NULL"` + DefaultCurrency string `xorm:"VARCHAR(3) NOT NULL"` + DefaultAccountId int64 FirstDayOfWeek WeekDay `xorm:"TINYINT NOT NULL"` TransactionEditScope TransactionEditScope `xorm:"TINYINT NOT NULL"` Deleted bool `xorm:"NOT NULL"` @@ -110,6 +111,7 @@ type UserBasicInfo struct { Email string `json:"email"` Nickname string `json:"nickname"` DefaultCurrency string `json:"defaultCurrency"` + DefaultAccountId int64 `json:"defaultAccountId,string"` FirstDayOfWeek WeekDay `json:"firstDayOfWeek"` TransactionEditScope TransactionEditScope `json:"transactionEditScope"` } @@ -137,6 +139,7 @@ type UserProfileUpdateRequest struct { Password string `json:"password" binding:"omitempty,min=6,max=128"` OldPassword string `json:"oldPassword" binding:"omitempty,min=6,max=128"` DefaultCurrency string `json:"defaultCurrency" binding:"omitempty,len=3,validCurrency"` + DefaultAccountId int64 `json:"defaultAccountId,string" binding:"omitempty,min=1"` FirstDayOfWeek *WeekDay `json:"firstDayOfWeek" binding:"omitempty,min=0,max=6"` TransactionEditScope *TransactionEditScope `json:"transactionEditScope" binding:"omitempty,min=0,max=7"` } @@ -153,6 +156,7 @@ type UserProfileResponse struct { Email string `json:"email"` Nickname string `json:"nickname"` DefaultCurrency string `json:"defaultCurrency"` + DefaultAccountId int64 `json:"defaultAccountId,string"` FirstDayOfWeek WeekDay `json:"firstDayOfWeek"` TransactionEditScope TransactionEditScope `json:"transactionEditScope"` LastLoginAt int64 `json:"lastLoginAt"` @@ -207,6 +211,7 @@ func (u *User) ToUserBasicInfo() *UserBasicInfo { Email: u.Email, Nickname: u.Nickname, DefaultCurrency: u.DefaultCurrency, + DefaultAccountId: u.DefaultAccountId, FirstDayOfWeek: u.FirstDayOfWeek, TransactionEditScope: u.TransactionEditScope, } @@ -219,6 +224,7 @@ func (u *User) ToUserProfileResponse() *UserProfileResponse { Email: u.Email, Nickname: u.Nickname, DefaultCurrency: u.DefaultCurrency, + DefaultAccountId: u.DefaultAccountId, FirstDayOfWeek: u.FirstDayOfWeek, TransactionEditScope: u.TransactionEditScope, LastLoginAt: u.LastLoginUnixTime, diff --git a/pkg/services/users.go b/pkg/services/users.go index e3a68385..e5e70a16 100644 --- a/pkg/services/users.go +++ b/pkg/services/users.go @@ -190,6 +190,10 @@ func (s *UserService) UpdateUser(user *models.User) (keyProfileUpdated bool, err updateCols = append(updateCols, "default_currency") } + if user.DefaultAccountId > 0 { + updateCols = append(updateCols, "default_account_id") + } + if models.WEEKDAY_SUNDAY <= user.FirstDayOfWeek && user.FirstDayOfWeek <= models.WEEKDAY_SATURDAY { updateCols = append(updateCols, "first_day_of_week") } diff --git a/src/lib/services.js b/src/lib/services.js index 12f873b2..dd61868d 100644 --- a/src/lib/services.js +++ b/src/lib/services.js @@ -133,13 +133,14 @@ export default { getProfile: () => { return axios.get('v1/users/profile/get.json'); }, - updateProfile: ({ email, nickname, password, oldPassword, defaultCurrency, firstDayOfWeek, transactionEditScope }) => { + updateProfile: ({ email, nickname, password, oldPassword, defaultCurrency, defaultAccountId, firstDayOfWeek, transactionEditScope }) => { return axios.post('v1/users/profile/update.json', { email, nickname, password, oldPassword, defaultCurrency, + defaultAccountId, firstDayOfWeek, transactionEditScope }); diff --git a/src/locales/en.js b/src/locales/en.js index 15c0b41a..008709fc 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -523,6 +523,7 @@ export default { 'password is empty': 'Password is empty', 'user default currency is empty': 'User default currency is empty', 'user default currency is invalid': 'User default currency is invalid', + 'user default account is invalid': 'User default account is invalid', 'user not found': 'User not found', 'password is wrong': 'Password is wrong', 'username already exists': 'Username already exists', @@ -650,6 +651,7 @@ export default { 'Save': 'Save', 'Update': 'Update', 'None': 'None', + 'Not Specified': 'Not Specified', 'Done': 'Done', 'Continue': 'Continue', 'Status': 'Status', @@ -714,6 +716,7 @@ export default { 'Nickname': 'Nickname', 'Your nickname': 'Your nickname', 'Default Currency': 'Default Currency', + 'Default Account': 'Default Account', 'First Day of Week': 'First Day of Week', 'Editable Transaction Scope': 'Editable Transaction Scope', 'Today or later': 'Today or later', diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js index a2b88add..2a31bd9c 100644 --- a/src/locales/zh_Hans.js +++ b/src/locales/zh_Hans.js @@ -523,6 +523,7 @@ export default { 'password is empty': '密码为空', 'user default currency is empty': '用户默认货币为空', 'user default currency is invalid': '用户默认货币无效', + 'user default account is invalid': '用户默认账户无效', 'user not found': '找不到该用户', 'password is wrong': '密码错误', 'username already exists': '用户名已经存在', @@ -650,6 +651,7 @@ export default { 'Save': '保存', 'Update': '更新', 'None': '无', + 'Not Specified': '未指定', 'Done': '完成', 'Continue': '继续', 'Status': '状态', @@ -714,6 +716,7 @@ export default { 'Nickname': '昵称', 'Your nickname': '你的昵称', 'Default Currency': '默认货币', + 'Default Account': '默认账户', 'First Day of Week': '每周第一天', 'Editable Transaction Scope': '可编辑交易范围', 'Today or later': '今天或更晚', diff --git a/src/store/index.js b/src/store/index.js index 8d70a9ff..bb01a126 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -72,6 +72,7 @@ import { resetState, currentUserNickname, currentUserDefaultCurrency, + currentUserDefaultAccountId, currentUserFirstDayOfWeek, } from './user.js'; @@ -208,6 +209,7 @@ const stores = { // user currentUserNickname, currentUserDefaultCurrency, + currentUserDefaultAccountId, currentUserFirstDayOfWeek, // exchange rates diff --git a/src/store/user.js b/src/store/user.js index 9b62b940..488089e1 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -236,6 +236,7 @@ export function updateUserProfile(context, { profile, currentPassword }) { email: profile.email, nickname: profile.nickname, defaultCurrency: profile.defaultCurrency, + defaultAccountId: profile.defaultAccountId, firstDayOfWeek: profile.firstDayOfWeek, transactionEditScope: profile.transactionEditScope }).then(response => { @@ -346,6 +347,11 @@ export function currentUserDefaultCurrency(state) { return userInfo.defaultCurrency || state.defaultSetting.currency; } +export function currentUserDefaultAccountId(state) { + const userInfo = state.currentUserInfo || {}; + return userInfo.defaultAccountId || ''; +} + export function currentUserFirstDayOfWeek(state) { const userInfo = state.currentUserInfo || {}; return utils.isNumber(userInfo.firstDayOfWeek) ? userInfo.firstDayOfWeek : state.defaultSetting.firstDayOfWeek; diff --git a/src/views/mobile/transactions/Edit.vue b/src/views/mobile/transactions/Edit.vue index 6935883f..02fb3fcb 100644 --- a/src/views/mobile/transactions/Edit.vue +++ b/src/views/mobile/transactions/Edit.vue @@ -373,6 +373,9 @@ export default { defaultCurrency() { return this.$store.getters.currentUserDefaultCurrency; }, + defaultAccountId() { + return this.$store.getters.currentUserDefaultAccountId; + }, defaultFirstDayOfWeek() { return this.$store.getters.currentUserFirstDayOfWeek; }, @@ -643,11 +646,19 @@ export default { } if (!self.transaction.sourceAccountId) { - self.transaction.sourceAccountId = self.allVisibleAccounts[0].id; + if (self.defaultAccountId && self.allAccountsMap[self.defaultAccountId]) { + self.transaction.sourceAccountId = self.defaultAccountId; + } else { + self.transaction.sourceAccountId = self.allVisibleAccounts[0].id; + } } if (!self.transaction.destinationAccountId) { - self.transaction.destinationAccountId = self.allVisibleAccounts[0].id; + if (self.defaultAccountId && self.allAccountsMap[self.defaultAccountId]) { + self.transaction.destinationAccountId = self.defaultAccountId; + } else { + self.transaction.destinationAccountId = self.allVisibleAccounts[0].id; + } } } diff --git a/src/views/mobile/users/UserProfile.vue b/src/views/mobile/users/UserProfile.vue index 9e5c7a8e..765b33f7 100644 --- a/src/views/mobile/users/UserProfile.vue +++ b/src/views/mobile/users/UserProfile.vue @@ -93,6 +93,28 @@ + + + + + { + const promises = [ + self.$store.dispatch('loadAllAccounts', { force: false }), + self.$store.dispatch('getCurrentUserProfile') + ]; + + Promise.all(promises).then(responses => { + const profile = responses[1]; + self.oldProfile.email = profile.email; self.oldProfile.nickname = profile.nickname; self.oldProfile.defaultCurrency = profile.defaultCurrency; + self.oldProfile.defaultAccountId = profile.defaultAccountId; self.oldProfile.firstDayOfWeek = profile.firstDayOfWeek; self.oldProfile.transactionEditScope = profile.transactionEditScope; self.newProfile.email = self.oldProfile.email self.newProfile.nickname = self.oldProfile.nickname; self.newProfile.defaultCurrency = self.oldProfile.defaultCurrency; + self.newProfile.defaultAccountId = self.oldProfile.defaultAccountId; self.newProfile.firstDayOfWeek = self.oldProfile.firstDayOfWeek; self.newProfile.transactionEditScope = self.oldProfile.transactionEditScope;