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("[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)
+18 -4
View File
@@ -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
+1
View File
@@ -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")
)
+13 -7
View File
@@ -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,
+4
View File
@@ -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")
}
+2 -1
View File
@@ -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
});
+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 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',
+3
View File
@@ -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': '今天或更晚',
+2
View File
@@ -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
+6
View File
@@ -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;
+13 -2
View File
@@ -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;
}
}
}
+46 -2
View File
@@ -93,6 +93,28 @@
</select>
</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
class="list-item-with-header-and-title list-item-no-item-after"
:header="$t('First Day of Week')"
@@ -145,6 +167,7 @@ export default {
email: '',
nickname: '',
defaultCurrency: '',
defaultAccountId: '',
firstDayOfWeek: 0,
transactionEditScope: 1
},
@@ -152,6 +175,7 @@ export default {
email: '',
nickname: '',
defaultCurrency: '',
defaultAccountId: '',
firstDayOfWeek: 0,
transactionEditScope: 1
},
@@ -159,13 +183,23 @@ export default {
loading: true,
loadingError: null,
saving: false,
showInputPasswordSheet: false
showInputPasswordSheet: false,
showAccountSheet: false
};
},
computed: {
allCurrencies() {
return this.$locale.getAllCurrencies();
},
allAccounts() {
return this.$store.getters.allPlainAccounts;
},
allVisibleAccounts() {
return this.$store.getters.allVisiblePlainAccounts;
},
allCategorizedAccounts() {
return this.$utilities.getCategorizedAccounts(this.allVisibleAccounts);
},
allWeekDays() {
return this.$constants.datetime.allWeekDays;
},
@@ -209,6 +243,7 @@ export default {
this.newProfile.email === this.oldProfile.email &&
this.newProfile.nickname === this.oldProfile.nickname &&
this.newProfile.defaultCurrency === this.oldProfile.defaultCurrency &&
this.newProfile.defaultAccountId === this.oldProfile.defaultAccountId &&
this.newProfile.firstDayOfWeek === this.oldProfile.firstDayOfWeek &&
this.newProfile.transactionEditScope === this.oldProfile.transactionEditScope) {
return 'Nothing has been modified';
@@ -246,16 +281,25 @@ export default {
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.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;