support set user default account

This commit is contained in:
MaysWind
2022-04-18 00:16:47 +08:00
parent c5a101aad2
commit 9a79606565
12 changed files with 112 additions and 16 deletions
+1
View File
@@ -399,6 +399,7 @@ func printUserInfo(user *models.User) {
fmt.Printf("[Password] %s\n", user.Password) fmt.Printf("[Password] %s\n", user.Password)
fmt.Printf("[Salt] %s\n", user.Salt) fmt.Printf("[Salt] %s\n", user.Salt)
fmt.Printf("[DefaultCurrency] %s\n", user.DefaultCurrency) fmt.Printf("[DefaultCurrency] %s\n", user.DefaultCurrency)
fmt.Printf("[DefaultAccountId] %s\n", user.DefaultAccountId)
fmt.Printf("[FirstDayOfWeek] %s\n", user.FirstDayOfWeek) fmt.Printf("[FirstDayOfWeek] %s\n", user.FirstDayOfWeek)
fmt.Printf("[TransactionEditScope] %s\n", user.TransactionEditScope) fmt.Printf("[TransactionEditScope] %s\n", user.TransactionEditScope)
fmt.Printf("[Deleted] %t\n", user.Deleted) fmt.Printf("[Deleted] %t\n", user.Deleted)
+18 -4
View File
@@ -15,15 +15,17 @@ import (
// UsersApi represents user api // UsersApi represents user api
type UsersApi struct { type UsersApi struct {
users *services.UserService users *services.UserService
tokens *services.TokenService tokens *services.TokenService
accounts *services.AccountService
} }
// Initialize a user api singleton instance // Initialize a user api singleton instance
var ( var (
Users = &UsersApi{ Users = &UsersApi{
users: services.Users, users: services.Users,
tokens: services.Tokens, tokens: services.Tokens,
accounts: services.Accounts,
} }
) )
@@ -165,6 +167,18 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.Context) (interface{}, *errs
anythingUpdate = true 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 { if userUpdateReq.FirstDayOfWeek != nil && *userUpdateReq.FirstDayOfWeek != user.FirstDayOfWeek {
user.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek user.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek
userNew.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek userNew.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek
+1
View File
@@ -21,4 +21,5 @@ var (
ErrUsernameAlreadyExists = NewNormalError(NormalSubcategoryUser, 12, http.StatusBadRequest, "username already exists") ErrUsernameAlreadyExists = NewNormalError(NormalSubcategoryUser, 12, http.StatusBadRequest, "username already exists")
ErrUserEmailAlreadyExists = NewNormalError(NormalSubcategoryUser, 13, http.StatusBadRequest, "email already exists") ErrUserEmailAlreadyExists = NewNormalError(NormalSubcategoryUser, 13, http.StatusBadRequest, "email already exists")
ErrUserRegistrationNotAllowed = NewNormalError(NormalSubcategoryUser, 14, http.StatusBadRequest, "user registration not allowed") ErrUserRegistrationNotAllowed = NewNormalError(NormalSubcategoryUser, 14, http.StatusBadRequest, "user registration not allowed")
ErrUserDefaultAccountIsInvalid = NewNormalError(NormalSubcategoryUser, 15, http.StatusBadRequest, "user default account is invalid")
) )
+13 -7
View File
@@ -87,13 +87,14 @@ func (s TransactionEditScope) String() string {
// User represents user data stored in database // User represents user data stored in database
type User struct { type User struct {
Uid int64 `xorm:"PK"` Uid int64 `xorm:"PK"`
Username string `xorm:"VARCHAR(32) UNIQUE NOT NULL"` Username string `xorm:"VARCHAR(32) UNIQUE NOT NULL"`
Email string `xorm:"VARCHAR(100) UNIQUE NOT NULL"` Email string `xorm:"VARCHAR(100) UNIQUE NOT NULL"`
Nickname string `xorm:"VARCHAR(64) NOT NULL"` Nickname string `xorm:"VARCHAR(64) NOT NULL"`
Password string `xorm:"VARCHAR(64) NOT NULL"` Password string `xorm:"VARCHAR(64) NOT NULL"`
Salt string `xorm:"VARCHAR(10) NOT NULL"` Salt string `xorm:"VARCHAR(10) NOT NULL"`
DefaultCurrency string `xorm:"VARCHAR(3) NOT NULL"` DefaultCurrency string `xorm:"VARCHAR(3) NOT NULL"`
DefaultAccountId int64
FirstDayOfWeek WeekDay `xorm:"TINYINT NOT NULL"` FirstDayOfWeek WeekDay `xorm:"TINYINT NOT NULL"`
TransactionEditScope TransactionEditScope `xorm:"TINYINT NOT NULL"` TransactionEditScope TransactionEditScope `xorm:"TINYINT NOT NULL"`
Deleted bool `xorm:"NOT NULL"` Deleted bool `xorm:"NOT NULL"`
@@ -110,6 +111,7 @@ type UserBasicInfo struct {
Email string `json:"email"` Email string `json:"email"`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
DefaultCurrency string `json:"defaultCurrency"` DefaultCurrency string `json:"defaultCurrency"`
DefaultAccountId int64 `json:"defaultAccountId,string"`
FirstDayOfWeek WeekDay `json:"firstDayOfWeek"` FirstDayOfWeek WeekDay `json:"firstDayOfWeek"`
TransactionEditScope TransactionEditScope `json:"transactionEditScope"` TransactionEditScope TransactionEditScope `json:"transactionEditScope"`
} }
@@ -137,6 +139,7 @@ type UserProfileUpdateRequest struct {
Password string `json:"password" binding:"omitempty,min=6,max=128"` Password string `json:"password" binding:"omitempty,min=6,max=128"`
OldPassword string `json:"oldPassword" 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"` 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"` FirstDayOfWeek *WeekDay `json:"firstDayOfWeek" binding:"omitempty,min=0,max=6"`
TransactionEditScope *TransactionEditScope `json:"transactionEditScope" binding:"omitempty,min=0,max=7"` TransactionEditScope *TransactionEditScope `json:"transactionEditScope" binding:"omitempty,min=0,max=7"`
} }
@@ -153,6 +156,7 @@ type UserProfileResponse struct {
Email string `json:"email"` Email string `json:"email"`
Nickname string `json:"nickname"` Nickname string `json:"nickname"`
DefaultCurrency string `json:"defaultCurrency"` DefaultCurrency string `json:"defaultCurrency"`
DefaultAccountId int64 `json:"defaultAccountId,string"`
FirstDayOfWeek WeekDay `json:"firstDayOfWeek"` FirstDayOfWeek WeekDay `json:"firstDayOfWeek"`
TransactionEditScope TransactionEditScope `json:"transactionEditScope"` TransactionEditScope TransactionEditScope `json:"transactionEditScope"`
LastLoginAt int64 `json:"lastLoginAt"` LastLoginAt int64 `json:"lastLoginAt"`
@@ -207,6 +211,7 @@ func (u *User) ToUserBasicInfo() *UserBasicInfo {
Email: u.Email, Email: u.Email,
Nickname: u.Nickname, Nickname: u.Nickname,
DefaultCurrency: u.DefaultCurrency, DefaultCurrency: u.DefaultCurrency,
DefaultAccountId: u.DefaultAccountId,
FirstDayOfWeek: u.FirstDayOfWeek, FirstDayOfWeek: u.FirstDayOfWeek,
TransactionEditScope: u.TransactionEditScope, TransactionEditScope: u.TransactionEditScope,
} }
@@ -219,6 +224,7 @@ func (u *User) ToUserProfileResponse() *UserProfileResponse {
Email: u.Email, Email: u.Email,
Nickname: u.Nickname, Nickname: u.Nickname,
DefaultCurrency: u.DefaultCurrency, DefaultCurrency: u.DefaultCurrency,
DefaultAccountId: u.DefaultAccountId,
FirstDayOfWeek: u.FirstDayOfWeek, FirstDayOfWeek: u.FirstDayOfWeek,
TransactionEditScope: u.TransactionEditScope, TransactionEditScope: u.TransactionEditScope,
LastLoginAt: u.LastLoginUnixTime, LastLoginAt: u.LastLoginUnixTime,
+4
View File
@@ -190,6 +190,10 @@ func (s *UserService) UpdateUser(user *models.User) (keyProfileUpdated bool, err
updateCols = append(updateCols, "default_currency") 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 { if models.WEEKDAY_SUNDAY <= user.FirstDayOfWeek && user.FirstDayOfWeek <= models.WEEKDAY_SATURDAY {
updateCols = append(updateCols, "first_day_of_week") updateCols = append(updateCols, "first_day_of_week")
} }
+2 -1
View File
@@ -133,13 +133,14 @@ export default {
getProfile: () => { getProfile: () => {
return axios.get('v1/users/profile/get.json'); 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', { return axios.post('v1/users/profile/update.json', {
email, email,
nickname, nickname,
password, password,
oldPassword, oldPassword,
defaultCurrency, defaultCurrency,
defaultAccountId,
firstDayOfWeek, firstDayOfWeek,
transactionEditScope transactionEditScope
}); });
+3
View File
@@ -523,6 +523,7 @@ export default {
'password is empty': 'Password is empty', 'password is empty': 'Password is empty',
'user default currency is empty': 'User default currency is empty', 'user default currency is empty': 'User default currency is empty',
'user default currency is invalid': 'User default currency is invalid', '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', 'user not found': 'User not found',
'password is wrong': 'Password is wrong', 'password is wrong': 'Password is wrong',
'username already exists': 'Username already exists', 'username already exists': 'Username already exists',
@@ -650,6 +651,7 @@ export default {
'Save': 'Save', 'Save': 'Save',
'Update': 'Update', 'Update': 'Update',
'None': 'None', 'None': 'None',
'Not Specified': 'Not Specified',
'Done': 'Done', 'Done': 'Done',
'Continue': 'Continue', 'Continue': 'Continue',
'Status': 'Status', 'Status': 'Status',
@@ -714,6 +716,7 @@ export default {
'Nickname': 'Nickname', 'Nickname': 'Nickname',
'Your nickname': 'Your nickname', 'Your nickname': 'Your nickname',
'Default Currency': 'Default Currency', 'Default Currency': 'Default Currency',
'Default Account': 'Default Account',
'First Day of Week': 'First Day of Week', 'First Day of Week': 'First Day of Week',
'Editable Transaction Scope': 'Editable Transaction Scope', 'Editable Transaction Scope': 'Editable Transaction Scope',
'Today or later': 'Today or later', 'Today or later': 'Today or later',
+3
View File
@@ -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 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': '未指定',
'Done': '完成', 'Done': '完成',
'Continue': '继续', 'Continue': '继续',
'Status': '状态', 'Status': '状态',
@@ -714,6 +716,7 @@ export default {
'Nickname': '昵称', 'Nickname': '昵称',
'Your nickname': '你的昵称', 'Your nickname': '你的昵称',
'Default Currency': '默认货币', 'Default Currency': '默认货币',
'Default Account': '默认账户',
'First Day of Week': '每周第一天', 'First Day of Week': '每周第一天',
'Editable Transaction Scope': '可编辑交易范围', 'Editable Transaction Scope': '可编辑交易范围',
'Today or later': '今天或更晚', 'Today or later': '今天或更晚',
+2
View File
@@ -72,6 +72,7 @@ import {
resetState, resetState,
currentUserNickname, currentUserNickname,
currentUserDefaultCurrency, currentUserDefaultCurrency,
currentUserDefaultAccountId,
currentUserFirstDayOfWeek, currentUserFirstDayOfWeek,
} from './user.js'; } from './user.js';
@@ -208,6 +209,7 @@ const stores = {
// user // user
currentUserNickname, currentUserNickname,
currentUserDefaultCurrency, currentUserDefaultCurrency,
currentUserDefaultAccountId,
currentUserFirstDayOfWeek, currentUserFirstDayOfWeek,
// exchange rates // exchange rates
+6
View File
@@ -236,6 +236,7 @@ export function updateUserProfile(context, { profile, currentPassword }) {
email: profile.email, email: profile.email,
nickname: profile.nickname, nickname: profile.nickname,
defaultCurrency: profile.defaultCurrency, defaultCurrency: profile.defaultCurrency,
defaultAccountId: profile.defaultAccountId,
firstDayOfWeek: profile.firstDayOfWeek, firstDayOfWeek: profile.firstDayOfWeek,
transactionEditScope: profile.transactionEditScope transactionEditScope: profile.transactionEditScope
}).then(response => { }).then(response => {
@@ -346,6 +347,11 @@ export function currentUserDefaultCurrency(state) {
return userInfo.defaultCurrency || state.defaultSetting.currency; return userInfo.defaultCurrency || state.defaultSetting.currency;
} }
export function currentUserDefaultAccountId(state) {
const userInfo = state.currentUserInfo || {};
return userInfo.defaultAccountId || '';
}
export function currentUserFirstDayOfWeek(state) { export function currentUserFirstDayOfWeek(state) {
const userInfo = state.currentUserInfo || {}; const userInfo = state.currentUserInfo || {};
return utils.isNumber(userInfo.firstDayOfWeek) ? userInfo.firstDayOfWeek : state.defaultSetting.firstDayOfWeek; return utils.isNumber(userInfo.firstDayOfWeek) ? userInfo.firstDayOfWeek : state.defaultSetting.firstDayOfWeek;
+13 -2
View File
@@ -373,6 +373,9 @@ export default {
defaultCurrency() { defaultCurrency() {
return this.$store.getters.currentUserDefaultCurrency; return this.$store.getters.currentUserDefaultCurrency;
}, },
defaultAccountId() {
return this.$store.getters.currentUserDefaultAccountId;
},
defaultFirstDayOfWeek() { defaultFirstDayOfWeek() {
return this.$store.getters.currentUserFirstDayOfWeek; return this.$store.getters.currentUserFirstDayOfWeek;
}, },
@@ -643,11 +646,19 @@ export default {
} }
if (!self.transaction.sourceAccountId) { 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) { 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;
}
} }
} }
+46 -2
View File
@@ -93,6 +93,28 @@
</select> </select>
</f7-list-item> </f7-list-item>
<f7-list-item
class="list-item-with-header-and-title"
link="#"
:class="{ 'disabled': !allVisibleAccounts.length }"
:header="$t('Default Account')"
:title="newProfile.defaultAccountId | optionName(allAccounts, 'id', 'name', $t('Not Specified'))"
@click="showAccountSheet = true"
>
<two-column-list-item-selection-sheet primary-key-field="id" primary-value-field="category"
primary-title-field="name"
primary-icon-field="icon" primary-icon-type="account"
primary-sub-items-field="accounts"
:primary-title-i18n="true"
secondary-key-field="id" secondary-value-field="id"
secondary-title-field="name"
secondary-icon-field="icon" secondary-icon-type="account" secondary-color-field="color"
:items="allCategorizedAccounts"
:show.sync="showAccountSheet"
v-model="newProfile.defaultAccountId">
</two-column-list-item-selection-sheet>
</f7-list-item>
<f7-list-item <f7-list-item
class="list-item-with-header-and-title list-item-no-item-after" class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('First Day of Week')" :header="$t('First Day of Week')"
@@ -145,6 +167,7 @@ export default {
email: '', email: '',
nickname: '', nickname: '',
defaultCurrency: '', defaultCurrency: '',
defaultAccountId: '',
firstDayOfWeek: 0, firstDayOfWeek: 0,
transactionEditScope: 1 transactionEditScope: 1
}, },
@@ -152,6 +175,7 @@ export default {
email: '', email: '',
nickname: '', nickname: '',
defaultCurrency: '', defaultCurrency: '',
defaultAccountId: '',
firstDayOfWeek: 0, firstDayOfWeek: 0,
transactionEditScope: 1 transactionEditScope: 1
}, },
@@ -159,13 +183,23 @@ export default {
loading: true, loading: true,
loadingError: null, loadingError: null,
saving: false, saving: false,
showInputPasswordSheet: false showInputPasswordSheet: false,
showAccountSheet: false
}; };
}, },
computed: { computed: {
allCurrencies() { allCurrencies() {
return this.$locale.getAllCurrencies(); return this.$locale.getAllCurrencies();
}, },
allAccounts() {
return this.$store.getters.allPlainAccounts;
},
allVisibleAccounts() {
return this.$store.getters.allVisiblePlainAccounts;
},
allCategorizedAccounts() {
return this.$utilities.getCategorizedAccounts(this.allVisibleAccounts);
},
allWeekDays() { allWeekDays() {
return this.$constants.datetime.allWeekDays; return this.$constants.datetime.allWeekDays;
}, },
@@ -209,6 +243,7 @@ export default {
this.newProfile.email === this.oldProfile.email && this.newProfile.email === this.oldProfile.email &&
this.newProfile.nickname === this.oldProfile.nickname && this.newProfile.nickname === this.oldProfile.nickname &&
this.newProfile.defaultCurrency === this.oldProfile.defaultCurrency && this.newProfile.defaultCurrency === this.oldProfile.defaultCurrency &&
this.newProfile.defaultAccountId === this.oldProfile.defaultAccountId &&
this.newProfile.firstDayOfWeek === this.oldProfile.firstDayOfWeek && this.newProfile.firstDayOfWeek === this.oldProfile.firstDayOfWeek &&
this.newProfile.transactionEditScope === this.oldProfile.transactionEditScope) { this.newProfile.transactionEditScope === this.oldProfile.transactionEditScope) {
return 'Nothing has been modified'; return 'Nothing has been modified';
@@ -246,16 +281,25 @@ export default {
self.loading = true; self.loading = true;
self.$store.dispatch('getCurrentUserProfile').then(profile => { 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.email = profile.email;
self.oldProfile.nickname = profile.nickname; self.oldProfile.nickname = profile.nickname;
self.oldProfile.defaultCurrency = profile.defaultCurrency; self.oldProfile.defaultCurrency = profile.defaultCurrency;
self.oldProfile.defaultAccountId = profile.defaultAccountId;
self.oldProfile.firstDayOfWeek = profile.firstDayOfWeek; self.oldProfile.firstDayOfWeek = profile.firstDayOfWeek;
self.oldProfile.transactionEditScope = profile.transactionEditScope; self.oldProfile.transactionEditScope = profile.transactionEditScope;
self.newProfile.email = self.oldProfile.email self.newProfile.email = self.oldProfile.email
self.newProfile.nickname = self.oldProfile.nickname; self.newProfile.nickname = self.oldProfile.nickname;
self.newProfile.defaultCurrency = self.oldProfile.defaultCurrency; self.newProfile.defaultCurrency = self.oldProfile.defaultCurrency;
self.newProfile.defaultAccountId = self.oldProfile.defaultAccountId;
self.newProfile.firstDayOfWeek = self.oldProfile.firstDayOfWeek; self.newProfile.firstDayOfWeek = self.oldProfile.firstDayOfWeek;
self.newProfile.transactionEditScope = self.oldProfile.transactionEditScope; self.newProfile.transactionEditScope = self.oldProfile.transactionEditScope;