mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 01:04:25 +08:00
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)
|
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()
|
uid := c.GetCurrentUid()
|
||||||
user, err := a.users.GetUserById(uid)
|
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)
|
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]
|
transactionTagIds := allTransactionTagIds[transaction.TransactionId]
|
||||||
transactionResps.Items[i] = transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
|
transactionResps.Items[i] = transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
|
||||||
}
|
}
|
||||||
@@ -155,6 +162,13 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (interfac
|
|||||||
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
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()
|
uid := c.GetCurrentUid()
|
||||||
user, err := a.users.GetUserById(uid)
|
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)
|
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]
|
transactionTagIds := allTransactionTagIds[transaction.TransactionId]
|
||||||
transactionResps[i] = transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
|
transactionResps[i] = transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
|
||||||
}
|
}
|
||||||
@@ -253,6 +267,13 @@ func (a *TransactionsApi) TransactionGetHandler(c *core.Context) (interface{}, *
|
|||||||
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
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()
|
uid := c.GetCurrentUid()
|
||||||
user, err := a.users.GetUserById(uid)
|
user, err := a.users.GetUserById(uid)
|
||||||
|
|
||||||
@@ -304,7 +325,7 @@ func (a *TransactionsApi) TransactionGetHandler(c *core.Context) (interface{}, *
|
|||||||
return nil, errs.ErrOperationFailed
|
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]
|
transactionTagIds := allTransactionTagIds[transaction.TransactionId]
|
||||||
transactionResp := transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
|
transactionResp := transaction.ToTransactionInfoResponse(transactionTagIds, transactionEditable)
|
||||||
|
|
||||||
@@ -497,6 +518,13 @@ func (a *TransactionsApi) TransactionDeleteHandler(c *core.Context) (interface{}
|
|||||||
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
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()
|
uid := c.GetCurrentUid()
|
||||||
user, err := a.users.GetUserById(uid)
|
user, err := a.users.GetUserById(uid)
|
||||||
|
|
||||||
@@ -520,7 +548,7 @@ func (a *TransactionsApi) TransactionDeleteHandler(c *core.Context) (interface{}
|
|||||||
return nil, errs.ErrTransactionTypeInvalid
|
return nil, errs.ErrTransactionTypeInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionEditable := user.CanEditTransactionByTransactionTime(transaction.TransactionTime, transactionDeleteReq.UtcOffset)
|
transactionEditable := user.CanEditTransactionByTransactionTime(transaction.TransactionTime, utcOffset)
|
||||||
|
|
||||||
if !transactionEditable {
|
if !transactionEditable {
|
||||||
return nil, errs.ErrCannotDeleteTransactionWithThisTransactionTime
|
return nil, errs.ErrCannotDeleteTransactionWithThisTransactionTime
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ const requestIdFieldKey = "REQUEST_ID"
|
|||||||
const tokenClaimsFieldKey = "TOKEN_CLAIMS"
|
const tokenClaimsFieldKey = "TOKEN_CLAIMS"
|
||||||
const responseErrorFieldKey = "RESPONSE_ERROR"
|
const responseErrorFieldKey = "RESPONSE_ERROR"
|
||||||
|
|
||||||
|
const clientTimezoneOffsetHeaderName = "X-Timezone-Offset"
|
||||||
|
|
||||||
// Context represents the request and response context
|
// Context represents the request and response context
|
||||||
type Context struct {
|
type Context struct {
|
||||||
*gin.Context
|
*gin.Context
|
||||||
@@ -67,6 +69,18 @@ func (c *Context) GetCurrentUid() int64 {
|
|||||||
return uid
|
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
|
// SetResponseError sets the response error
|
||||||
func (c *Context) SetResponseError(error *errs.Error) {
|
func (c *Context) SetResponseError(error *errs.Error) {
|
||||||
c.Set(responseErrorFieldKey, error)
|
c.Set(responseErrorFieldKey, error)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ var (
|
|||||||
ErrFailedToRequestRemoteApi = NewNormalError(NormalSubcategoryGlobal, 5, http.StatusBadRequest, "failed to request third party api")
|
ErrFailedToRequestRemoteApi = NewNormalError(NormalSubcategoryGlobal, 5, http.StatusBadRequest, "failed to request third party api")
|
||||||
ErrPageIndexInvalid = NewNormalError(NormalSubcategoryGlobal, 6, http.StatusBadRequest, "page index is invalid")
|
ErrPageIndexInvalid = NewNormalError(NormalSubcategoryGlobal, 6, http.StatusBadRequest, "page index is invalid")
|
||||||
ErrPageCountInvalid = NewNormalError(NormalSubcategoryGlobal, 7, http.StatusBadRequest, "page count 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
|
// GetParameterInvalidMessage returns specific error message for invalid parameter error
|
||||||
|
|||||||
@@ -56,13 +56,13 @@ type TransactionCreateRequest struct {
|
|||||||
Type TransactionType `json:"type" binding:"required"`
|
Type TransactionType `json:"type" binding:"required"`
|
||||||
CategoryId int64 `json:"categoryId,string"`
|
CategoryId int64 `json:"categoryId,string"`
|
||||||
Time int64 `json:"time" binding:"required,min=1"`
|
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"`
|
SourceAccountId int64 `json:"sourceAccountId,string" binding:"required,min=1"`
|
||||||
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"min=0"`
|
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"min=0"`
|
||||||
SourceAmount int64 `json:"sourceAmount" binding:"min=-99999999999,max=99999999999"`
|
SourceAmount int64 `json:"sourceAmount" binding:"min=-99999999999,max=99999999999"`
|
||||||
DestinationAmount int64 `json:"destinationAmount" binding:"min=-99999999999,max=99999999999"`
|
DestinationAmount int64 `json:"destinationAmount" binding:"min=-99999999999,max=99999999999"`
|
||||||
TagIds []string `json:"tagIds"`
|
TagIds []string `json:"tagIds"`
|
||||||
Comment string `json:"comment" binding:"max=255"`
|
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
|
// TransactionModifyRequest represents all parameters of transaction modification request
|
||||||
@@ -70,13 +70,13 @@ type TransactionModifyRequest struct {
|
|||||||
Id int64 `json:"id,string" binding:"required,min=1"`
|
Id int64 `json:"id,string" binding:"required,min=1"`
|
||||||
CategoryId int64 `json:"categoryId,string"`
|
CategoryId int64 `json:"categoryId,string"`
|
||||||
Time int64 `json:"time" binding:"required,min=1"`
|
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"`
|
SourceAccountId int64 `json:"sourceAccountId,string" binding:"required,min=1"`
|
||||||
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"min=0"`
|
DestinationAccountId int64 `json:"destinationAccountId,string" binding:"min=0"`
|
||||||
SourceAmount int64 `json:"sourceAmount" binding:"min=-99999999999,max=99999999999"`
|
SourceAmount int64 `json:"sourceAmount" binding:"min=-99999999999,max=99999999999"`
|
||||||
DestinationAmount int64 `json:"destinationAmount" binding:"min=-99999999999,max=99999999999"`
|
DestinationAmount int64 `json:"destinationAmount" binding:"min=-99999999999,max=99999999999"`
|
||||||
TagIds []string `json:"tagIds"`
|
TagIds []string `json:"tagIds"`
|
||||||
Comment string `json:"comment" binding:"max=255"`
|
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
|
// 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"`
|
MaxTime int64 `form:"max_time" binding:"min=0"`
|
||||||
MinTime int64 `form:"min_time" binding:"min=0"`
|
MinTime int64 `form:"min_time" binding:"min=0"`
|
||||||
Count int `form:"count" binding:"required,min=1,max=50"`
|
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
|
// TransactionListInMonthByPageRequest represents all parameters of transaction listing by month request
|
||||||
@@ -101,19 +100,16 @@ type TransactionListInMonthByPageRequest struct {
|
|||||||
Keyword string `form:"keyword"`
|
Keyword string `form:"keyword"`
|
||||||
Page int `form:"page" binding:"required,min=1"`
|
Page int `form:"page" binding:"required,min=1"`
|
||||||
Count int `form:"count" binding:"required,min=1,max=50"`
|
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
|
// TransactionGetRequest represents all parameters of transaction getting request
|
||||||
type TransactionGetRequest struct {
|
type TransactionGetRequest struct {
|
||||||
Id int64 `form:"id,string" binding:"required,min=1"`
|
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
|
// TransactionDeleteRequest represents all parameters of transaction deleting request
|
||||||
type TransactionDeleteRequest struct {
|
type TransactionDeleteRequest struct {
|
||||||
Id int64 `json:"id,string" binding:"required,min=1"`
|
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
|
// TransactionInfoResponse represents a view-object of transaction
|
||||||
@@ -139,7 +135,7 @@ type TransactionInfoPageWrapperResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsEditable returns whether this transaction can be edited
|
// 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) {
|
if currentUser == nil || !currentUser.CanEditTransactionByTransactionTime(t.TransactionTime, utcOffset) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -124,7 +124,7 @@ type UserProfileResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CanEditTransactionByTransactionTime returns whether this user can edit transaction with specified transaction time
|
// 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 {
|
if u.TransactionEditScope == TRANSACTION_EDIT_SCOPE_NONE {
|
||||||
return false
|
return false
|
||||||
} else if u.TransactionEditScope == TRANSACTION_EDIT_SCOPE_ALL {
|
} else if u.TransactionEditScope == TRANSACTION_EDIT_SCOPE_ALL {
|
||||||
@@ -141,7 +141,7 @@ func (u *User) CanEditTransactionByTransactionTime(transactionTime int64, utcOff
|
|||||||
|
|
||||||
_, serverUtcOffset := now.Zone()
|
_, serverUtcOffset := now.Zone()
|
||||||
serverTodayFirstUnixTime := now.Unix() - int64(now.Hour()*60*60+now.Minute()*60+now.Second())
|
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 {
|
if u.TransactionEditScope == TRANSACTION_EDIT_SCOPE_TODAY_OR_LATER {
|
||||||
return transactionUnixTime >= clientTodayFirstUnixTime
|
return transactionUnixTime >= clientTodayFirstUnixTime
|
||||||
|
|||||||
+5
-7
@@ -16,6 +16,8 @@ axios.interceptors.request.use(config => {
|
|||||||
config.headers.Authorization = `Bearer ${token}`;
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.headers['X-Timezone-Offset'] = utils.getTimezoneOffsetMinutes();
|
||||||
|
|
||||||
if (needBlockRequest && !config.ignoreBlocked) {
|
if (needBlockRequest && !config.ignoreBlocked) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
blockedRequests.push(newToken => {
|
blockedRequests.push(newToken => {
|
||||||
@@ -251,12 +253,10 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
getTransactions: ({ maxTime, minTime, type, categoryId, accountId, keyword }) => {
|
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`);
|
||||||
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}`);
|
|
||||||
},
|
},
|
||||||
getTransaction: ({ id }) => {
|
getTransaction: ({ id }) => {
|
||||||
const utcOffset = utils.getTimezoneOffsetMinutes();
|
return axios.get(`v1/transactions/get.json?id=${id}`);
|
||||||
return axios.get(`v1/transactions/get.json?id=${id}&utc_offset=${utcOffset}`);
|
|
||||||
},
|
},
|
||||||
addTransaction: ({ type, categoryId, time, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, tagIds, comment, utcOffset }) => {
|
addTransaction: ({ type, categoryId, time, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, tagIds, comment, utcOffset }) => {
|
||||||
return axios.post('v1/transactions/add.json', {
|
return axios.post('v1/transactions/add.json', {
|
||||||
@@ -288,10 +288,8 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
deleteTransaction: ({ id }) => {
|
deleteTransaction: ({ id }) => {
|
||||||
const utcOffset = utils.getTimezoneOffsetMinutes();
|
|
||||||
return axios.post('v1/transactions/delete.json', {
|
return axios.post('v1/transactions/delete.json', {
|
||||||
id,
|
id
|
||||||
utcOffset
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getAllTransactionCategories: () => {
|
getAllTransactionCategories: () => {
|
||||||
|
|||||||
@@ -491,6 +491,7 @@ export default {
|
|||||||
'operation failed': 'Operation failed',
|
'operation failed': 'Operation failed',
|
||||||
'nothing will be updated': 'Nothing will be updated',
|
'nothing will be updated': 'Nothing will be updated',
|
||||||
'failed to request third party api': 'Failed to request third party api',
|
'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',
|
'user id is invalid': 'User ID is invalid',
|
||||||
'username is empty': 'Username is empty',
|
'username is empty': 'Username is empty',
|
||||||
'email is empty': 'Email is empty',
|
'email is empty': 'Email is empty',
|
||||||
|
|||||||
@@ -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': '客户端时区时间差异无效',
|
||||||
'user id is invalid': '用户ID无效',
|
'user id is invalid': '用户ID无效',
|
||||||
'username is empty': '用户名为空',
|
'username is empty': '用户名为空',
|
||||||
'email is empty': '电子邮箱为空',
|
'email is empty': '电子邮箱为空',
|
||||||
|
|||||||
Reference in New Issue
Block a user