move query parameter utc_offset to header
This commit is contained in:
+32
-4
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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: () => {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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': '电子邮箱为空',
|
||||
|
||||
Reference in New Issue
Block a user