add transaction tag index
This commit is contained in:
@@ -107,5 +107,13 @@ func updateAllDatabaseTablesStructure() error {
|
||||
log.BootInfof("[database.updateAllDatabaseTablesStructure] transaction tag table maintained successfully")
|
||||
}
|
||||
|
||||
err = datastore.Container.UserDataStore.SyncStructs(new(models.TransactionTagIndex))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
log.BootInfof("[database.updateAllDatabaseTablesStructure] transaction tag index table maintained successfully")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ func (a *TransactionTagsApi) TagDeleteHandler(c *core.Context) (interface{}, *er
|
||||
}
|
||||
|
||||
uid := c.GetCurrentUid()
|
||||
err = a.tags.DeleteTags(uid, []int64{tagDeleteReq.Id})
|
||||
err = a.tags.DeleteTag(uid, tagDeleteReq.Id)
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transaction_tags.TagDeleteHandler] failed to delete tag \"id:%d\" for user \"uid:%d\", because %s", tagDeleteReq.Id, uid, err.Error())
|
||||
|
||||
+60
-8
@@ -8,15 +8,18 @@ import (
|
||||
"github.com/mayswind/lab/pkg/log"
|
||||
"github.com/mayswind/lab/pkg/models"
|
||||
"github.com/mayswind/lab/pkg/services"
|
||||
"github.com/mayswind/lab/pkg/utils"
|
||||
)
|
||||
|
||||
type TransactionsApi struct {
|
||||
transactions *services.TransactionService
|
||||
transactions *services.TransactionService
|
||||
transactionTags *services.TransactionTagService
|
||||
}
|
||||
|
||||
var (
|
||||
Transactions = &TransactionsApi{
|
||||
transactions: services.Transactions,
|
||||
transactions: services.Transactions,
|
||||
transactionTags: services.TransactionTags,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -43,11 +46,25 @@ func (a *TransactionsApi) TransactionListHandler(c *core.Context) (interface{},
|
||||
finalCount = len(transactions)
|
||||
}
|
||||
|
||||
transactionIds := make([]int64, finalCount)
|
||||
|
||||
for i := 0; i < finalCount; i++ {
|
||||
transactionIds[i] = transactions[i].TransactionId
|
||||
}
|
||||
|
||||
allTransactionTagIds, err := a.transactionTags.GetAllTagIdsOfTransactions(uid, transactionIds)
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionListHandler] failed to get transactions tag ids for user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
transactionResps := &models.TransactionInfoPageWrapperResponse{}
|
||||
transactionResps.Items = make(models.TransactionInfoResponseSlice, finalCount)
|
||||
|
||||
for i := 0; i < finalCount; i++ {
|
||||
transactionResps.Items[i] = transactions[i].ToTransactionInfoResponse(nil)
|
||||
transactionTagIds := allTransactionTagIds[transactions[i].TransactionId]
|
||||
transactionResps.Items[i] = transactions[i].ToTransactionInfoResponse(transactionTagIds)
|
||||
}
|
||||
|
||||
sort.Sort(transactionResps.Items)
|
||||
@@ -76,10 +93,24 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.Context) (interfac
|
||||
return nil, errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
transactionIds := make([]int64, len(transactions))
|
||||
|
||||
for i := 0; i < len(transactions); i++ {
|
||||
transactionIds[i] = transactions[i].TransactionId
|
||||
}
|
||||
|
||||
allTransactionTagIds, err := a.transactionTags.GetAllTagIdsOfTransactions(uid, transactionIds)
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionMonthListHandler] failed to get transactions tag ids for user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
transactionResps := make([]*models.TransactionInfoResponse, len(transactions))
|
||||
|
||||
for i := 0; i < len(transactions); i++ {
|
||||
transactionResps[i] = transactions[i].ToTransactionInfoResponse(nil)
|
||||
transactionTagIds := allTransactionTagIds[transactions[i].TransactionId]
|
||||
transactionResps[i] = transactions[i].ToTransactionInfoResponse(transactionTagIds)
|
||||
}
|
||||
|
||||
return transactionResps, nil
|
||||
@@ -102,7 +133,15 @@ func (a *TransactionsApi) TransactionGetHandler(c *core.Context) (interface{}, *
|
||||
return nil, errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
transactionResp := transaction.ToTransactionInfoResponse(nil)
|
||||
allTransactionTagIds, err := a.transactionTags.GetAllTagIdsOfTransactions(uid, []int64{transaction.TransactionId})
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionGetHandler] failed to get transactions tag ids for user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
transactionTagIds := allTransactionTagIds[transaction.TransactionId]
|
||||
transactionResp := transaction.ToTransactionInfoResponse(transactionTagIds)
|
||||
|
||||
return transactionResp, nil
|
||||
}
|
||||
@@ -142,7 +181,7 @@ func (a *TransactionsApi) TransactionCreateHandler(c *core.Context) (interface{}
|
||||
uid := c.GetCurrentUid()
|
||||
transaction := a.createNewTransactionModel(uid, &transactionCreateReq)
|
||||
|
||||
err = a.transactions.CreateTransaction(transaction)
|
||||
err = a.transactions.CreateTransaction(transaction, transactionCreateReq.TagIds)
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionCreateHandler] failed to create transaction \"id:%d\" for user \"uid:%d\", because %s", transaction.TransactionId, uid, err.Error())
|
||||
@@ -173,6 +212,17 @@ func (a *TransactionsApi) TransactionModifyHandler(c *core.Context) (interface{}
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
allTransactionTagIds, err := a.transactionTags.GetAllTagIdsOfTransactions(uid, []int64{transaction.TransactionId})
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionModifyHandler] failed to get transactions tag ids for user \"uid:%d\", because %s", uid, err.Error())
|
||||
return nil, errs.ErrOperationFailed
|
||||
}
|
||||
|
||||
transactionTagIds := allTransactionTagIds[transaction.TransactionId]
|
||||
addTransactionTagIds := utils.Int64SliceMinus(transactionModifyReq.TagIds, transactionTagIds)
|
||||
removeTransactionTagIds := utils.Int64SliceMinus(transactionTagIds, transactionModifyReq.TagIds)
|
||||
|
||||
newTransaction := &models.Transaction{
|
||||
TransactionId: transaction.TransactionId,
|
||||
Uid: uid,
|
||||
@@ -191,11 +241,13 @@ func (a *TransactionsApi) TransactionModifyHandler(c *core.Context) (interface{}
|
||||
newTransaction.DestinationAccountId == transaction.DestinationAccountId &&
|
||||
newTransaction.SourceAmount == transaction.SourceAmount &&
|
||||
newTransaction.DestinationAmount == transaction.DestinationAmount &&
|
||||
newTransaction.Comment == transaction.Comment {
|
||||
newTransaction.Comment == transaction.Comment &&
|
||||
len(addTransactionTagIds) < 1 &&
|
||||
len(removeTransactionTagIds) < 1 {
|
||||
return nil, errs.ErrNothingWillBeUpdated
|
||||
}
|
||||
|
||||
err = a.transactions.ModifyTransaction(newTransaction)
|
||||
err = a.transactions.ModifyTransaction(newTransaction, addTransactionTagIds, removeTransactionTagIds)
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[transactions.TransactionModifyHandler] failed to update transaction \"id:%d\" for user \"uid:%d\", because %s", transactionModifyReq.Id, uid, err.Error())
|
||||
|
||||
@@ -3,8 +3,9 @@ package errs
|
||||
import "net/http"
|
||||
|
||||
var (
|
||||
ErrTransactionTagIdInvalid = NewNormalError(NORMAL_SUBCATEGORY_TAG, 0, http.StatusBadRequest, "transaction tag id is invalid")
|
||||
ErrTransactionTagNotFound = NewNormalError(NORMAL_SUBCATEGORY_TAG, 1, http.StatusBadRequest, "transaction tag not found")
|
||||
ErrTransactionTagNameIsEmpty = NewNormalError(NORMAL_SUBCATEGORY_TAG, 2, http.StatusBadRequest, "transaction tag name is empty")
|
||||
ErrTransactionTagNameAlreadyExists = NewNormalError(NORMAL_SUBCATEGORY_TAG, 3, http.StatusBadRequest, "transaction tag name already exists")
|
||||
ErrTransactionTagIdInvalid = NewNormalError(NORMAL_SUBCATEGORY_TAG, 0, http.StatusBadRequest, "transaction tag id is invalid")
|
||||
ErrTransactionTagNotFound = NewNormalError(NORMAL_SUBCATEGORY_TAG, 1, http.StatusBadRequest, "transaction tag not found")
|
||||
ErrTransactionTagNameIsEmpty = NewNormalError(NORMAL_SUBCATEGORY_TAG, 2, http.StatusBadRequest, "transaction tag name is empty")
|
||||
ErrTransactionTagNameAlreadyExists = NewNormalError(NORMAL_SUBCATEGORY_TAG, 3, http.StatusBadRequest, "transaction tag name already exists")
|
||||
ErrTransactionTagInUseCannotBeDeleted = NewNormalError(NORMAL_SUBCATEGORY_TAG, 4, http.StatusBadRequest, "transaction tag is in use and cannot be deleted")
|
||||
)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package models
|
||||
|
||||
type TransactionTagIndex struct {
|
||||
Uid int64 `xorm:"PK INDEX(IDX_transaction_tag_index_uid_tag_id_transaction_time) INDEX(IDX_transaction_tag_index_uid_transaction_id)"`
|
||||
TagId int64 `xorm:"PK INDEX(IDX_transaction_tag_index_uid_tag_id_transaction_time)"`
|
||||
TransactionId int64 `xorm:"PK INDEX(IDX_transaction_tag_index_uid_transaction_id)"`
|
||||
TransactionTime int64 `xorm:"INDEX(IDX_transaction_tag_index_uid_tag_id_transaction_time) NOT NULL"`
|
||||
CreatedUnixTime int64
|
||||
UpdatedUnixTime int64
|
||||
}
|
||||
@@ -78,6 +78,32 @@ func (s *TransactionTagService) GetMaxDisplayOrder(uid int64) (int, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TransactionTagService) GetAllTagIdsOfTransactions(uid int64, transactionIds []int64) (map[int64][]int64, error) {
|
||||
if uid <= 0 {
|
||||
return nil, errs.ErrUserIdInvalid
|
||||
}
|
||||
|
||||
var tagIndexs []*models.TransactionTagIndex
|
||||
err := s.UserDataDB(uid).Where("uid=?", uid).In("transaction_id", transactionIds).Find(&tagIndexs)
|
||||
|
||||
allTransactionTagIds := make(map[int64][]int64)
|
||||
|
||||
for i := 0; i < len(tagIndexs); i++ {
|
||||
tagIndex := tagIndexs[i]
|
||||
|
||||
var transactionTagIds []int64
|
||||
|
||||
if _, exists := allTransactionTagIds[tagIndex.TransactionId]; exists {
|
||||
transactionTagIds = allTransactionTagIds[tagIndex.TransactionId]
|
||||
}
|
||||
|
||||
transactionTagIds = append(transactionTagIds, tagIndex.TagId)
|
||||
allTransactionTagIds[tagIndex.TransactionId] = transactionTagIds
|
||||
}
|
||||
|
||||
return allTransactionTagIds, err
|
||||
}
|
||||
|
||||
func (s *TransactionTagService) CreateTag(tag *models.TransactionTag) error {
|
||||
if tag.Uid <= 0 {
|
||||
return errs.ErrUserIdInvalid
|
||||
@@ -180,13 +206,19 @@ func (s *TransactionTagService) ModifyTagDisplayOrders(uid int64, tags []*models
|
||||
})
|
||||
}
|
||||
|
||||
func (s *TransactionTagService) DeleteTags(uid int64, ids []int64) error {
|
||||
func (s *TransactionTagService) DeleteTag(uid int64, tagId int64) error {
|
||||
if uid <= 0 {
|
||||
return errs.ErrUserIdInvalid
|
||||
}
|
||||
|
||||
return s.UserDataDB(uid).DoTransaction(func(sess *xorm.Session) error {
|
||||
deletedRows, err := sess.In("tag_id", ids).Where("uid=?", uid).Delete(&models.TransactionTag{})
|
||||
exists, err := sess.Cols("uid", "tag_id").Where("uid=? AND tag_id=?", uid, tagId).Limit(1).Exist(&models.TransactionTagIndex{})
|
||||
|
||||
if exists {
|
||||
return errs.ErrTransactionTagInUseCannotBeDeleted
|
||||
}
|
||||
|
||||
deletedRows, err := sess.ID(tagId).Where("uid=?", uid).Delete(&models.TransactionTag{})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -122,7 +122,7 @@ func (s *TransactionService) GetMonthTransactionCount(uid int64, year int64, mon
|
||||
return s.UserDataDB(uid).Where("uid=? AND deleted=? AND transaction_time>=? AND transaction_time<?", uid, false, startUnixTime, endUnixTime).Count(&models.Transaction{})
|
||||
}
|
||||
|
||||
func (s *TransactionService) CreateTransaction(transaction *models.Transaction) error {
|
||||
func (s *TransactionService) CreateTransaction(transaction *models.Transaction, tagIds []int64) error {
|
||||
if transaction.Uid <= 0 {
|
||||
return errs.ErrUserIdInvalid
|
||||
}
|
||||
@@ -143,11 +143,26 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction)
|
||||
return errs.ErrTransactionTypeInvalid
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
|
||||
transaction.TransactionId = s.GenerateUuid(uuid.UUID_TYPE_TRANSACTION)
|
||||
transaction.TransactionTime = utils.GetMinTransactionTimeFromUnixTime(utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime))
|
||||
|
||||
transaction.CreatedUnixTime = time.Now().Unix()
|
||||
transaction.UpdatedUnixTime = time.Now().Unix()
|
||||
transaction.CreatedUnixTime = now
|
||||
transaction.UpdatedUnixTime = now
|
||||
|
||||
tagIds = utils.ToUniqueInt64Slice(tagIds)
|
||||
transactionTagIndexs := make([]*models.TransactionTagIndex, len(tagIds))
|
||||
|
||||
for i := 0; i < len(tagIds); i++ {
|
||||
transactionTagIndexs[i] = &models.TransactionTagIndex{
|
||||
Uid: transaction.Uid,
|
||||
TagId: tagIds[i],
|
||||
TransactionId: transaction.TransactionId,
|
||||
CreatedUnixTime: now,
|
||||
UpdatedUnixTime: now,
|
||||
}
|
||||
}
|
||||
|
||||
return s.UserDataDB(transaction.Uid).DoTransaction(func(sess *xorm.Session) error {
|
||||
// Get and verify source and destination account
|
||||
@@ -204,6 +219,28 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction)
|
||||
return errs.ErrTransactionCategoryTypeInvalid
|
||||
}
|
||||
|
||||
// Get and verify tags
|
||||
if len(transactionTagIndexs) > 0 {
|
||||
var tags []*models.TransactionTag
|
||||
err := sess.Where("uid=? AND deleted=?", transaction.Uid, false).In("tag_ids", tagIds).Find(&tags)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tagMap := make(map[int64]*models.TransactionTag)
|
||||
|
||||
for i := 0; i < len(tags); i++ {
|
||||
tagMap[tags[i].TagId] = tags[i]
|
||||
}
|
||||
|
||||
for i := 0; i < len(transactionTagIndexs); i++ {
|
||||
if _, exists := tagMap[transactionTagIndexs[i].TagId]; !exists {
|
||||
return errs.ErrTransactionTagNotFound
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify balance modification transaction and calculate real amount
|
||||
if transaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
otherTransactionExists, err := sess.Where("uid=? AND deleted=? AND destination_account_id=?", transaction.Uid, false, destinationAccount.AccountId).Limit(1).Exist(&models.Transaction{})
|
||||
@@ -245,6 +282,18 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction)
|
||||
}
|
||||
}
|
||||
|
||||
// Insert transaction tag index
|
||||
if len(transactionTagIndexs) > 0 {
|
||||
for i := 0; i < len(transactionTagIndexs); i++ {
|
||||
transactionTagIndex := transactionTagIndexs[i]
|
||||
_, err := sess.Insert(transactionTagIndex)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update account table
|
||||
if transaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
destinationAccount.UpdatedUnixTime = time.Now().Unix()
|
||||
@@ -297,7 +346,7 @@ func (s *TransactionService) CreateTransaction(transaction *models.Transaction)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *TransactionService) ModifyTransaction(transaction *models.Transaction) error {
|
||||
func (s *TransactionService) ModifyTransaction(transaction *models.Transaction, addTagIds []int64, removeTagIds []int64) error {
|
||||
if transaction.Uid <= 0 {
|
||||
return errs.ErrUserIdInvalid
|
||||
}
|
||||
@@ -310,6 +359,21 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction)
|
||||
transaction.UpdatedUnixTime = now
|
||||
updateCols = append(updateCols, "updated_unix_time")
|
||||
|
||||
addTagIds = utils.ToUniqueInt64Slice(addTagIds)
|
||||
removeTagIds = utils.ToUniqueInt64Slice(removeTagIds)
|
||||
|
||||
transactionTagIndexs := make([]*models.TransactionTagIndex, len(addTagIds))
|
||||
|
||||
for i := 0; i < len(addTagIds); i++ {
|
||||
transactionTagIndexs[i] = &models.TransactionTagIndex{
|
||||
Uid: transaction.Uid,
|
||||
TagId: addTagIds[i],
|
||||
TransactionId: transaction.TransactionId,
|
||||
CreatedUnixTime: now,
|
||||
UpdatedUnixTime: now,
|
||||
}
|
||||
}
|
||||
|
||||
err := s.UserDB().DoTransaction(func(sess *xorm.Session) error {
|
||||
// Get and verify current transaction
|
||||
oldTransaction := &models.Transaction{}
|
||||
@@ -435,6 +499,28 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction)
|
||||
updateCols = append(updateCols, "comment")
|
||||
}
|
||||
|
||||
// Get and verify tags
|
||||
if len(transactionTagIndexs) > 0 {
|
||||
var tags []*models.TransactionTag
|
||||
err := sess.Where("uid=? AND deleted=?", transaction.Uid, false).In("tag_ids", addTagIds).Find(&tags)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tagMap := make(map[int64]*models.TransactionTag)
|
||||
|
||||
for i := 0; i < len(tags); i++ {
|
||||
tagMap[tags[i].TagId] = tags[i]
|
||||
}
|
||||
|
||||
for i := 0; i < len(transactionTagIndexs); i++ {
|
||||
if _, exists := tagMap[transactionTagIndexs[i].TagId]; !exists {
|
||||
return errs.ErrTransactionTagNotFound
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update transaction row
|
||||
updatedRows, err := sess.ID(transaction.TransactionId).Cols(updateCols...).Where("uid=? AND deleted=?", transaction.Uid, false).Update(transaction)
|
||||
|
||||
@@ -444,6 +530,30 @@ func (s *TransactionService) ModifyTransaction(transaction *models.Transaction)
|
||||
return errs.ErrTransactionNotFound
|
||||
}
|
||||
|
||||
// Update transaction tag index
|
||||
if len(removeTagIds) > 0 {
|
||||
deletedRows, err := sess.Where("uid=?", transaction.Uid).In("tag_id", removeTagIds).Delete(&models.TransactionTagIndex{})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if deletedRows < 1 {
|
||||
return errs.ErrTransactionTagNotFound
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if len(transactionTagIndexs) > 0 {
|
||||
for i := 0; i < len(transactionTagIndexs); i++ {
|
||||
transactionTagIndex := transactionTagIndexs[i]
|
||||
_, err := sess.Insert(transactionTagIndex)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update account table
|
||||
if oldTransaction.Type == models.TRANSACTION_TYPE_MODIFY_BALANCE {
|
||||
if transaction.SourceAccountId != oldTransaction.SourceAccountId {
|
||||
|
||||
@@ -17,3 +17,40 @@ func IsStringSliceEuqals(s1, s2 []string) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func Int64SliceMinus(s1, s2 []int64) []int64 {
|
||||
if s1 == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
s2ItemsMap := make(map[int64]bool)
|
||||
var ret []int64
|
||||
|
||||
for i := 0; i < len(s2); i++ {
|
||||
s2ItemsMap[s2[i]] = true
|
||||
}
|
||||
|
||||
for i := 0; i < len(s1); i++ {
|
||||
if _, exists := s2ItemsMap[s1[i]]; !exists {
|
||||
ret = append(ret, s1[i])
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func ToUniqueInt64Slice(items []int64) []int64 {
|
||||
var uniqueItems []int64
|
||||
itemExistMap := make(map[int64]bool)
|
||||
|
||||
for i := 0; i < len(items); i++ {
|
||||
item := items[i]
|
||||
|
||||
if _, exists := itemExistMap[item]; !exists {
|
||||
uniqueItems = append(uniqueItems, item)
|
||||
itemExistMap[item] = true
|
||||
}
|
||||
}
|
||||
|
||||
return uniqueItems
|
||||
}
|
||||
|
||||
@@ -329,6 +329,7 @@ export default {
|
||||
'transaction tag not found': 'Transaction tag is not found',
|
||||
'transaction tag name is empty': 'Transaction tag title is empty',
|
||||
'transaction tag name already exists': 'Transaction tag title already exists',
|
||||
'transaction tag is in use and cannot be deleted': 'Transaction tag is in use and it cannot be deleted',
|
||||
},
|
||||
'parameter': {
|
||||
'id': 'ID',
|
||||
|
||||
@@ -329,6 +329,7 @@ export default {
|
||||
'transaction tag not found': '交易标签不存在',
|
||||
'transaction tag name is empty': '交易标签标题不能为空',
|
||||
'transaction tag name already exists': '交易标签标题已经存在',
|
||||
'transaction tag is in use and cannot be deleted': '交易标签正在被使用,无法删除',
|
||||
},
|
||||
'parameter': {
|
||||
'id': 'ID',
|
||||
|
||||
Reference in New Issue
Block a user