move query parameter utc_offset to header

This commit is contained in:
MaysWind
2021-03-13 21:02:02 +08:00
parent 53340fe9fb
commit bfb56fad48
8 changed files with 59 additions and 20 deletions
+32 -4
View File
@@ -41,6 +41,13 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{},
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
}
utcOffset, err := c.GetClientTimezoneOffset()
if err != nil {
log.WarnfWithRequestId(c, "[transactions.TransactionListHandler] cannot get client timezone offset, because %s", err.Error())
return nil, errs.ErrClientTimezoneOffsetInvalid
}
uid := c.GetCurrentUid()
user, err := a.users.GetUserById(uid)
@@ -131,7 +138,7 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{},
transaction = a.transactions.GetRelatedTransferTransaction(transaction, transaction.RelatedId)
}
transactionEditable := transaction.IsEditable(user, transactionListReq.UtcOffset, allAccounts[transaction.AccountId], allAccounts[transaction.RelatedAccountId])
transactionEditable := transaction.IsEditable(user, utcOffset, allAccounts[transaction.AccountId], allAccounts[transaction.RelatedAccountId])
transactionTagIds := allTransactionTagIds[transaction.TransactionId]
transactionResps.Items[i] = transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
}
@@ -155,6 +162,13 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (interfac
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
}
utcOffset, err := c.GetClientTimezoneOffset()
if err != nil {
log.WarnfWithRequestId(c, "[transactions.TransactionMonthListHandler] cannot get client timezone offset, because %s", err.Error())
return nil, errs.ErrClientTimezoneOffsetInvalid
}
uid := c.GetCurrentUid()
user, err := a.users.GetUserById(uid)
@@ -235,7 +249,7 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (interfac
transaction = a.transactions.GetRelatedTransferTransaction(transaction, transaction.RelatedId)
}
transactionEditable := transaction.IsEditable(user, transactionListReq.UtcOffset, allAccounts[transaction.AccountId], allAccounts[transaction.RelatedAccountId])
transactionEditable := transaction.IsEditable(user, utcOffset, allAccounts[transaction.AccountId], allAccounts[transaction.RelatedAccountId])
transactionTagIds := allTransactionTagIds[transaction.TransactionId]
transactionResps[i] = transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
}
@@ -253,6 +267,13 @@ func (a *TransactionsApi) TransactionGetHandler(c *core.Context) (interface{}, *
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
}
utcOffset, err := c.GetClientTimezoneOffset()
if err != nil {
log.WarnfWithRequestId(c, "[transactions.TransactionGetHandler] cannot get client timezone offset, because %s", err.Error())
return nil, errs.ErrClientTimezoneOffsetInvalid
}
uid := c.GetCurrentUid()
user, err := a.users.GetUserById(uid)
@@ -304,7 +325,7 @@ func (a *TransactionsApi) TransactionGetHandler(c *core.Context) (interface{}, *
return nil, errs.ErrOperationFailed
}
transactionEditable := transaction.IsEditable(user, transactionGetReq.UtcOffset, accountMap[transaction.AccountId], accountMap[transaction.RelatedAccountId])
transactionEditable := transaction.IsEditable(user, utcOffset, accountMap[transaction.AccountId], accountMap[transaction.RelatedAccountId])
transactionTagIds := allTransactionTagIds[transaction.TransactionId]
transactionResp := transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
@@ -497,6 +518,13 @@ func (a *TransactionsApi) TransactionDeleteHandler(c *core.Context) (interface{}
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
}
utcOffset, err := c.GetClientTimezoneOffset()
if err != nil {
log.WarnfWithRequestId(c, "[transactions.TransactionDeleteHandler] cannot get client timezone offset, because %s", err.Error())
return nil, errs.ErrClientTimezoneOffsetInvalid
}
uid := c.GetCurrentUid()
user, err := a.users.GetUserById(uid)
@@ -520,7 +548,7 @@ func (a *TransactionsApi) TransactionDeleteHandler(c *core.Context) (interface{}
return nil, errs.ErrTransactionTypeInvalid
}
transactionEditable := user.CanEditTransactionByTransactionTime(transaction.TransactionTime, transactionDeleteReq.UtcOffset)
transactionEditable := user.CanEditTransactionByTransactionTime(transaction.TransactionTime, utcOffset)
if !transactionEditable {
return nil, errs.ErrCannotDeleteTransactionWithThisTransactionTime
+14
View File
@@ -12,6 +12,8 @@ const requestIdFieldKey = "REQUEST_ID"
const tokenClaimsFieldKey = "TOKEN_CLAIMS"
const responseErrorFieldKey = "RESPONSE_ERROR"
const clientTimezoneOffsetHeaderName = "X-Timezone-Offset"
// Context represents the request and response context
type Context struct {
*gin.Context
@@ -67,6 +69,18 @@ func (c *Context) GetCurrentUid() int64 {
return uid
}
// GetClientTimezoneOffset returns the client timezone offset
func (c *Context) GetClientTimezoneOffset() (int16, error) {
value := c.GetHeader(clientTimezoneOffsetHeaderName)
offset, err := strconv.Atoi(value)
if err != nil {
return 0, err
}
return int16(offset), nil
}
// SetResponseError sets the response error
func (c *Context) SetResponseError(error *errs.Error) {
c.Set(responseErrorFieldKey, error)
+1
View File
@@ -15,6 +15,7 @@ var (
ErrFailedToRequestRemoteApi = NewNormalError(NormalSubcategoryGlobal, 5, http.StatusBadRequest, "failed to request third party api")
ErrPageIndexInvalid = NewNormalError(NormalSubcategoryGlobal, 6, http.StatusBadRequest, "page index is invalid")
ErrPageCountInvalid = NewNormalError(NormalSubcategoryGlobal, 7, http.StatusBadRequest, "page count is invalid")
ErrClientTimezoneOffsetInvalid = NewNormalError(NormalSubcategoryGlobal, 8, http.StatusBadRequest, "client timezone offset is invalid")
)
// GetParameterInvalidMessage returns specific error message for invalid parameter error
+3 -7
View File
@@ -56,13 +56,13 @@ type TransactionCreateRequest struct {
Type TransactionType `json:"type" binding:"required"`
CategoryId int64 `json:"categoryId,string"`
Time int64 `json:"time" binding:"required,min=1"`
UtcOffset int16 `json:"utcOffset" binding:"min=-720,max=840"`
SourceAccountId int64 `json:"sourceAccountId,string" binding:"required,min=1"`
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"min=0"`
SourceAmount int64 `json:"sourceAmount" binding:"min=-99999999999,max=99999999999"`
DestinationAmount int64 `json:"destinationAmount" binding:"min=-99999999999,max=99999999999"`
TagIds []string `json:"tagIds"`
Comment string `json:"comment" binding:"max=255"`
UtcOffset int `json:"utcOffset" binding:"required,min=-720,max=840"`
}
// TransactionModifyRequest represents all parameters of transaction modification request
@@ -70,13 +70,13 @@ type TransactionModifyRequest struct {
Id int64 `json:"id,string" binding:"required,min=1"`
CategoryId int64 `json:"categoryId,string"`
Time int64 `json:"time" binding:"required,min=1"`
UtcOffset int16 `json:"utcOffset" binding:"min=-720,max=840"`
SourceAccountId int64 `json:"sourceAccountId,string" binding:"required,min=1"`
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"min=0"`
SourceAmount int64 `json:"sourceAmount" binding:"min=-99999999999,max=99999999999"`
DestinationAmount int64 `json:"destinationAmount" binding:"min=-99999999999,max=99999999999"`
TagIds []string `json:"tagIds"`
Comment string `json:"comment" binding:"max=255"`
UtcOffset int `json:"utcOffset" binding:"required,min=-720,max=840"`
}
// TransactionListByMaxTimeRequest represents all parameters of transaction listing by max time request
@@ -88,7 +88,6 @@ type TransactionListByMaxTimeRequest struct {
MaxTime int64 `form:"max_time" binding:"min=0"`
MinTime int64 `form:"min_time" binding:"min=0"`
Count int `form:"count" binding:"required,min=1,max=50"`
UtcOffset int `form:"utc_offset" binding:"required,min=-720,max=840"`
}
// TransactionListInMonthByPageRequest represents all parameters of transaction listing by month request
@@ -101,19 +100,16 @@ type TransactionListInMonthByPageRequest struct {
Keyword string `form:"keyword"`
Page int `form:"page" binding:"required,min=1"`
Count int `form:"count" binding:"required,min=1,max=50"`
UtcOffset int `form:"utc_offset" binding:"required,min=-720,max=840"`
}
// TransactionGetRequest represents all parameters of transaction getting request
type TransactionGetRequest struct {
Id int64 `form:"id,string" binding:"required,min=1"`
UtcOffset int `form:"utc_offset" binding:"required,min=-720,max=840"`
}
// TransactionDeleteRequest represents all parameters of transaction deleting request
type TransactionDeleteRequest struct {
Id int64 `json:"id,string" binding:"required,min=1"`
UtcOffset int `form:"utc_offset" binding:"required,min=-720,max=840"`
}
// TransactionInfoResponse represents a view-object of transaction
@@ -139,7 +135,7 @@ type TransactionInfoPageWrapperResponse struct {
}
// IsEditable returns whether this transaction can be edited
func (t *Transaction) IsEditable(currentUser *User, utcOffset int, account *Account, relatedAccount *Account) bool {
func (t *Transaction) IsEditable(currentUser *User, utcOffset int16, account *Account, relatedAccount *Account) bool {
if currentUser == nil || !currentUser.CanEditTransactionByTransactionTime(t.TransactionTime, utcOffset) {
return false
}
+2 -2
View File
@@ -124,7 +124,7 @@ type UserProfileResponse struct {
}
// CanEditTransactionByTransactionTime returns whether this user can edit transaction with specified transaction time
func (u *User) CanEditTransactionByTransactionTime(transactionTime int64, utcOffset int) bool {
func (u *User) CanEditTransactionByTransactionTime(transactionTime int64, utcOffset int16) bool {
if u.TransactionEditScope == TRANSACTION_EDIT_SCOPE_NONE {
return false
} else if u.TransactionEditScope == TRANSACTION_EDIT_SCOPE_ALL {
@@ -141,7 +141,7 @@ func (u *User) CanEditTransactionByTransactionTime(transactionTime int64, utcOff
_, serverUtcOffset := now.Zone()
serverTodayFirstUnixTime := now.Unix() - int64(now.Hour()*60*60+now.Minute()*60+now.Second())
clientTodayFirstUnixTime := serverTodayFirstUnixTime + int64(utcOffset*60-serverUtcOffset)
clientTodayFirstUnixTime := serverTodayFirstUnixTime + int64(utcOffset)*60 - int64(serverUtcOffset)
if u.TransactionEditScope == TRANSACTION_EDIT_SCOPE_TODAY_OR_LATER {
return transactionUnixTime >= clientTodayFirstUnixTime
+5 -7
View File
@@ -16,6 +16,8 @@ axios.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${token}`;
}
config.headers['X-Timezone-Offset'] = utils.getTimezoneOffsetMinutes();
if (needBlockRequest && !config.ignoreBlocked) {
return new Promise(resolve => {
blockedRequests.push(newToken => {
@@ -251,12 +253,10 @@ export default {
});
},
getTransactions: ({ maxTime, minTime, type, categoryId, accountId, keyword }) => {
const utcOffset = utils.getTimezoneOffsetMinutes();
return axios.get(`v1/transactions/list.json?max_time=${maxTime}&min_time=${minTime}&type=${type}&category_id=${categoryId}&account_id=${accountId}&keyword=${keyword}&count=50&utc_offset=${utcOffset}`);
return axios.get(`v1/transactions/list.json?max_time=${maxTime}&min_time=${minTime}&type=${type}&category_id=${categoryId}&account_id=${accountId}&keyword=${keyword}&count=50`);
},
getTransaction: ({ id }) => {
const utcOffset = utils.getTimezoneOffsetMinutes();
return axios.get(`v1/transactions/get.json?id=${id}&utc_offset=${utcOffset}`);
return axios.get(`v1/transactions/get.json?id=${id}`);
},
addTransaction: ({ type, categoryId, time, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, tagIds, comment, utcOffset }) => {
return axios.post('v1/transactions/add.json', {
@@ -288,10 +288,8 @@ export default {
});
},
deleteTransaction: ({ id }) => {
const utcOffset = utils.getTimezoneOffsetMinutes();
return axios.post('v1/transactions/delete.json', {
id,
utcOffset
id
});
},
getAllTransactionCategories: () => {
+1
View File
@@ -491,6 +491,7 @@ export default {
'operation failed': 'Operation failed',
'nothing will be updated': 'Nothing will be updated',
'failed to request third party api': 'Failed to request third party api',
'client timezone offset is invalid': 'Client timezone offset is invalid',
'user id is invalid': 'User ID is invalid',
'username is empty': 'Username is empty',
'email is empty': 'Email is empty',
+1
View File
@@ -491,6 +491,7 @@ export default {
'operation failed': '操作失败',
'nothing will be updated': '没有内容更新',
'failed to request third party api': '请求第三方接口失败',
'client timezone offset is invalid': '客户端时区时间差异无效',
'user id is invalid': '用户ID无效',
'username is empty': '用户名为空',
'email is empty': '电子邮箱为空',