add transaction gallery mode in transaction list page

This commit is contained in:
MaysWind
2026-05-11 00:25:55 +08:00
parent 11f2c9fff7
commit 563bef69cf
33 changed files with 453 additions and 87 deletions
+1 -1
View File
@@ -419,7 +419,7 @@ func (a *DataManagementsApi) getExportedFileContent(c *core.WebContext, fileType
minTransactionTime = utils.GetMinTransactionTimeFromUnixTime(exportTransactionDataReq.MinTime)
}
allTransactions, err := a.transactions.GetAllSpecifiedTransactions(c, uid, maxTransactionTime, minTransactionTime, exportTransactionDataReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, exportTransactionDataReq.AmountFilter, exportTransactionDataReq.Keyword, pageCountForDataExport, true)
allTransactions, err := a.transactions.GetAllSpecifiedTransactions(c, uid, maxTransactionTime, minTransactionTime, exportTransactionDataReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, exportTransactionDataReq.AmountFilter, exportTransactionDataReq.Keyword, false, pageCountForDataExport, true)
if err != nil {
log.Errorf(c, "[data_managements.getExportedFileContent] failed to all transactions user \"uid:%d\", because %s", uid, err.Error())
+5 -5
View File
@@ -97,7 +97,7 @@ func (a *TransactionsApi) TransactionCountHandler(c *core.WebContext) (any, *err
}
}
totalCount, err := a.transactions.GetTransactionCount(c, uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionCountReq.AmountFilter, transactionCountReq.Keyword)
totalCount, err := a.transactions.GetTransactionCount(c, uid, transactionCountReq.MaxTime, transactionCountReq.MinTime, transactionCountReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionCountReq.AmountFilter, transactionCountReq.Keyword, transactionCountReq.MustHavePictures)
if err != nil {
log.Errorf(c, "[transactions.TransactionCountHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
@@ -168,7 +168,7 @@ func (a *TransactionsApi) TransactionListHandler(c *core.WebContext) (any, *errs
var totalCount int64
if transactionListReq.WithCount {
totalCount, err = a.transactions.GetTransactionCount(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword)
totalCount, err = a.transactions.GetTransactionCount(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword, transactionListReq.MustHavePictures)
if err != nil {
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
@@ -176,7 +176,7 @@ func (a *TransactionsApi) TransactionListHandler(c *core.WebContext) (any, *errs
}
}
transactions, err := a.transactions.GetTransactionsByMaxTime(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword, transactionListReq.Page, transactionListReq.Count, true, true)
transactions, err := a.transactions.GetTransactionsByMaxTime(c, uid, transactionListReq.MaxTime, transactionListReq.MinTime, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword, transactionListReq.MustHavePictures, transactionListReq.Page, transactionListReq.Count, true, true)
if err != nil {
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", transactionListReq.MaxTime, uid, err.Error())
@@ -276,7 +276,7 @@ func (a *TransactionsApi) TransactionMonthListHandler(c *core.WebContext) (any,
}
}
transactions, err := a.transactions.GetTransactionsInMonthByPage(c, uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword)
transactions, err := a.transactions.GetTransactionsInMonthByPage(c, uid, transactionListReq.Year, transactionListReq.Month, transactionListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionListReq.AmountFilter, transactionListReq.Keyword, transactionListReq.MustHavePictures)
if err != nil {
log.Errorf(c, "[transactions.TransactionMonthListHandler] failed to get transactions in month \"%d-%d\" for user \"uid:%d\", because %s", transactionListReq.Year, transactionListReq.Month, uid, err.Error())
@@ -371,7 +371,7 @@ func (a *TransactionsApi) TransactionListAllHandler(c *core.WebContext) (any, *e
minTransactionTime = utils.GetMinTransactionTimeFromUnixTime(transactionAllListReq.StartTime)
}
allTransactions, err := a.transactions.GetAllSpecifiedTransactions(c, uid, maxTransactionTime, minTransactionTime, transactionAllListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionAllListReq.AmountFilter, transactionAllListReq.Keyword, pageCountForDataExport, true)
allTransactions, err := a.transactions.GetAllSpecifiedTransactions(c, uid, maxTransactionTime, minTransactionTime, transactionAllListReq.Type, allCategoryIds, allAccountIds, tagFilters, noTags, transactionAllListReq.AmountFilter, transactionAllListReq.Keyword, transactionAllListReq.MustHavePictures, pageCountForDataExport, true)
if err != nil {
log.Errorf(c, "[transactions.TransactionListAllHandler] failed to get all transactions for user \"uid:%d\", because %s", uid, err.Error())
+2 -2
View File
@@ -153,14 +153,14 @@ func (h *mcpQueryTransactionsToolHandler) Handle(c *core.WebContext, callToolReq
}
}
totalCount, err := services.GetTransactionService().GetTransactionCount(c, uid, maxTransactionTime, minTransactionTime, transactionType, filterCategoryIds, filterAccountIds, nil, false, "", queryTransactionsRequest.Keyword)
totalCount, err := services.GetTransactionService().GetTransactionCount(c, uid, maxTransactionTime, minTransactionTime, transactionType, filterCategoryIds, filterAccountIds, nil, false, "", queryTransactionsRequest.Keyword, false)
if err != nil {
log.Errorf(c, "[transactions.TransactionListHandler] failed to get transaction count for user \"uid:%d\", because %s", uid, err.Error())
return nil, nil, err
}
transactions, err := services.GetTransactionService().GetTransactionsByMaxTime(c, uid, maxTransactionTime, minTransactionTime, transactionType, filterCategoryIds, filterAccountIds, nil, false, "", queryTransactionsRequest.Keyword, queryTransactionsRequest.Page, queryTransactionsRequest.Count, false, true)
transactions, err := services.GetTransactionService().GetTransactionsByMaxTime(c, uid, maxTransactionTime, minTransactionTime, transactionType, filterCategoryIds, filterAccountIds, nil, false, "", queryTransactionsRequest.Keyword, false, queryTransactionsRequest.Page, queryTransactionsRequest.Count, false, true)
structuredResponse, response, err := h.createNewMCPQueryTransactionsResponse(c, &queryTransactionsRequest, transactions, totalCount, services.GetAccountService().GetAccountMapByList(allAccounts), services.GetTransactionCategoryService().GetCategoryMapByList(allCategories))
if err != nil {
+51 -47
View File
@@ -210,65 +210,69 @@ type TransactionTagFilter struct {
// TransactionCountRequest represents transaction count request
type TransactionCountRequest struct {
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MaxTime int64 `form:"max_time" binding:"min=0"` // Transaction time sequence id
MinTime int64 `form:"min_time" binding:"min=0"` // Transaction time sequence id
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MustHavePictures bool `form:"must_have_pictures"`
MaxTime int64 `form:"max_time" binding:"min=0"` // Transaction time sequence id
MinTime int64 `form:"min_time" binding:"min=0"` // Transaction time sequence id
}
// TransactionListByMaxTimeRequest represents all parameters of transaction listing by max time request
type TransactionListByMaxTimeRequest struct {
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MaxTime int64 `form:"max_time" binding:"min=0"` // Transaction time sequence id
MinTime int64 `form:"min_time" binding:"min=0"` // Transaction time sequence id
Page int32 `form:"page" binding:"min=0"`
Count int32 `form:"count" binding:"required,min=1,max=50"`
WithCount bool `form:"with_count"`
WithPictures bool `form:"with_pictures"`
TrimAccount bool `form:"trim_account"`
TrimCategory bool `form:"trim_category"`
TrimTag bool `form:"trim_tag"`
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MustHavePictures bool `form:"must_have_pictures"`
MaxTime int64 `form:"max_time" binding:"min=0"` // Transaction time sequence id
MinTime int64 `form:"min_time" binding:"min=0"` // Transaction time sequence id
Page int32 `form:"page" binding:"min=0"`
Count int32 `form:"count" binding:"required,min=1,max=50"`
WithCount bool `form:"with_count"`
WithPictures bool `form:"with_pictures"`
TrimAccount bool `form:"trim_account"`
TrimCategory bool `form:"trim_category"`
TrimTag bool `form:"trim_tag"`
}
// TransactionListInMonthByPageRequest represents all parameters of transaction listing by month request
type TransactionListInMonthByPageRequest struct {
Year int32 `form:"year" binding:"required,min=1"`
Month int32 `form:"month" binding:"required,min=1"`
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
WithPictures bool `form:"with_pictures"`
TrimAccount bool `form:"trim_account"`
TrimCategory bool `form:"trim_category"`
TrimTag bool `form:"trim_tag"`
Year int32 `form:"year" binding:"required,min=1"`
Month int32 `form:"month" binding:"required,min=1"`
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MustHavePictures bool `form:"must_have_pictures"`
WithPictures bool `form:"with_pictures"`
TrimAccount bool `form:"trim_account"`
TrimCategory bool `form:"trim_category"`
TrimTag bool `form:"trim_tag"`
}
// TransactionAllListRequest represents all parameters of all transaction listing request
type TransactionAllListRequest struct {
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
StartTime int64 `form:"start_time" binding:"min=0"`
EndTime int64 `form:"end_time" binding:"min=0"`
WithPictures bool `form:"with_pictures"`
TrimAccount bool `form:"trim_account"`
TrimCategory bool `form:"trim_category"`
TrimTag bool `form:"trim_tag"`
Type TransactionType `form:"type" binding:"min=0,max=4"`
CategoryIds string `form:"category_ids"`
AccountIds string `form:"account_ids"`
TagFilter string `form:"tag_filter" binding:"validTagFilter"`
AmountFilter string `form:"amount_filter" binding:"validAmountFilter"`
Keyword string `form:"keyword"`
MustHavePictures bool `form:"must_have_pictures"`
StartTime int64 `form:"start_time" binding:"min=0"`
EndTime int64 `form:"end_time" binding:"min=0"`
WithPictures bool `form:"with_pictures"`
TrimAccount bool `form:"trim_account"`
TrimCategory bool `form:"trim_category"`
TrimTag bool `form:"trim_tag"`
}
// TransactionReconciliationStatementRequest represents all parameters of transaction reconciliation statement request
+24 -10
View File
@@ -76,11 +76,11 @@ func (s *TransactionService) GetAllTransactions(c core.Context, uid int64, pageC
// GetAllTransactionsByMaxTime returns all transactions before given time
func (s *TransactionService) GetAllTransactionsByMaxTime(c core.Context, uid int64, maxTransactionTime int64, count int32, noDuplicated bool) ([]*models.Transaction, error) {
return s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, nil, nil, false, "", "", 1, count, false, noDuplicated)
return s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, nil, nil, false, "", "", false, 1, count, false, noDuplicated)
}
// GetAllSpecifiedTransactions returns all transactions that match given conditions
func (s *TransactionService) GetAllSpecifiedTransactions(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagFilters []*models.TransactionTagFilter, noTags bool, amountFilter string, keyword string, pageCount int32, noDuplicated bool) ([]*models.Transaction, error) {
func (s *TransactionService) GetAllSpecifiedTransactions(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagFilters []*models.TransactionTagFilter, noTags bool, amountFilter string, keyword string, mustHavePictures bool, pageCount int32, noDuplicated bool) ([]*models.Transaction, error) {
if maxTransactionTime <= 0 {
maxTransactionTime = utils.GetMaxTransactionTimeFromUnixTime(time.Now().Unix())
}
@@ -88,7 +88,7 @@ func (s *TransactionService) GetAllSpecifiedTransactions(c core.Context, uid int
var allTransactions []*models.Transaction
for maxTransactionTime > 0 {
transactions, err := s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagFilters, noTags, amountFilter, keyword, 1, pageCount, false, noDuplicated)
transactions, err := s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, minTransactionTime, transactionType, categoryIds, accountIds, tagFilters, noTags, amountFilter, keyword, mustHavePictures, 1, pageCount, false, noDuplicated)
if err != nil {
return nil, err
@@ -116,7 +116,7 @@ func (s *TransactionService) GetAllTransactionsInOneAccountWithAccountBalanceByM
var allTransactions []*models.Transaction
for maxTransactionTime > 0 {
transactions, err := s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, []int64{accountId}, nil, false, "", "", 1, pageCount, false, true)
transactions, err := s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, []int64{accountId}, nil, false, "", "", false, 1, pageCount, false, true)
if err != nil {
return nil, 0, 0, 0, 0, err
@@ -206,7 +206,7 @@ func (s *TransactionService) GetAllAccountsDailyOpeningAndClosingBalance(c core.
var allTransactions []*models.Transaction
for maxTransactionTime > 0 {
transactions, err := s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, nil, nil, false, "", "", 1, pageCountForLoadTransactionAmounts, false, false)
transactions, err := s.GetTransactionsByMaxTime(c, uid, maxTransactionTime, 0, 0, nil, nil, nil, false, "", "", false, 1, pageCountForLoadTransactionAmounts, false, false)
if err != nil {
return nil, err
@@ -323,7 +323,7 @@ func (s *TransactionService) GetAllAccountsDailyOpeningAndClosingBalance(c core.
}
// GetTransactionsByMaxTime returns transactions before given time
func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagFilters []*models.TransactionTagFilter, noTags bool, amountFilter string, keyword string, page int32, count int32, needOneMoreItem bool, noDuplicated bool) ([]*models.Transaction, error) {
func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagFilters []*models.TransactionTagFilter, noTags bool, amountFilter string, keyword string, mustHavePictures bool, page int32, count int32, needOneMoreItem bool, noDuplicated bool) ([]*models.Transaction, error) {
if uid <= 0 {
return nil, errs.ErrUserIdInvalid
}
@@ -360,6 +360,7 @@ func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64,
condition, conditionParams := s.buildTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionDbType, categoryIds, accountIds, tagFilters, amountFilter, keyword, noDuplicated)
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagFilters, noTags)
sess = s.appendFilterPicturesConditionToQuery(sess, uid, mustHavePictures)
err = sess.Limit(int(actualCount), int(count*(page-1))).OrderBy("transaction_time desc").Find(&transactions)
@@ -367,7 +368,7 @@ func (s *TransactionService) GetTransactionsByMaxTime(c core.Context, uid int64,
}
// GetTransactionsInMonthByPage returns all transactions in given year and month
func (s *TransactionService) GetTransactionsInMonthByPage(c core.Context, uid int64, year int32, month int32, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagFilters []*models.TransactionTagFilter, noTags bool, amountFilter string, keyword string) ([]*models.Transaction, error) {
func (s *TransactionService) GetTransactionsInMonthByPage(c core.Context, uid int64, year int32, month int32, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagFilters []*models.TransactionTagFilter, noTags bool, amountFilter string, keyword string, mustHavePictures bool) ([]*models.Transaction, error) {
if uid <= 0 {
return nil, errs.ErrUserIdInvalid
}
@@ -394,6 +395,7 @@ func (s *TransactionService) GetTransactionsInMonthByPage(c core.Context, uid in
condition, conditionParams := s.buildTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionDbType, categoryIds, accountIds, tagFilters, amountFilter, keyword, true)
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagFilters, noTags)
sess = s.appendFilterPicturesConditionToQuery(sess, uid, mustHavePictures)
err = sess.OrderBy("transaction_time desc").Find(&transactions)
@@ -452,11 +454,11 @@ func (s *TransactionService) GetTransactionsByTransactionIds(c core.Context, uid
// GetAllTransactionCount returns total count of transactions
func (s *TransactionService) GetAllTransactionCount(c core.Context, uid int64) (int64, error) {
return s.GetTransactionCount(c, uid, 0, 0, 0, nil, nil, nil, false, "", "")
return s.GetTransactionCount(c, uid, 0, 0, 0, nil, nil, nil, false, "", "", false)
}
// GetTransactionCount returns count of transactions
func (s *TransactionService) GetTransactionCount(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagFilters []*models.TransactionTagFilter, noTags bool, amountFilter string, keyword string) (int64, error) {
func (s *TransactionService) GetTransactionCount(c core.Context, uid int64, maxTransactionTime int64, minTransactionTime int64, transactionType models.TransactionType, categoryIds []int64, accountIds []int64, tagFilters []*models.TransactionTagFilter, noTags bool, amountFilter string, keyword string, mustHavePictures bool) (int64, error) {
if uid <= 0 {
return 0, errs.ErrUserIdInvalid
}
@@ -475,6 +477,7 @@ func (s *TransactionService) GetTransactionCount(c core.Context, uid int64, maxT
condition, conditionParams := s.buildTransactionQueryCondition(uid, maxTransactionTime, minTransactionTime, transactionDbType, categoryIds, accountIds, tagFilters, amountFilter, keyword, true)
sess := s.UserDataDB(uid).NewSession(c).Where(condition, conditionParams...)
sess = s.appendFilterTagIdsConditionToQuery(sess, uid, maxTransactionTime, minTransactionTime, tagFilters, noTags)
sess = s.appendFilterPicturesConditionToQuery(sess, uid, mustHavePictures)
return sess.Count(&models.Transaction{})
}
@@ -1964,7 +1967,7 @@ func (s *TransactionService) DeleteAllTransactionsOfAccount(c core.Context, uid
return errs.ErrAccountIdInvalid
}
transactions, err := s.GetAllSpecifiedTransactions(c, uid, 0, 0, 0, nil, []int64{accountId}, nil, false, "", "", pageCount, true)
transactions, err := s.GetAllSpecifiedTransactions(c, uid, 0, 0, 0, nil, []int64{accountId}, nil, false, "", "", false, pageCount, true)
if err != nil {
return err
@@ -2897,6 +2900,17 @@ func (s *TransactionService) appendFilterTagIdsConditionToQuery(sess *xorm.Sessi
return sess
}
func (s *TransactionService) appendFilterPicturesConditionToQuery(sess *xorm.Session, uid int64, mustHavePictures bool) *xorm.Session {
if !mustHavePictures {
return sess
}
subQuery := builder.Select("transaction_id").From("transaction_picture_info").Where(builder.And(builder.Eq{"uid": uid}, builder.Eq{"deleted": false}, builder.Neq{"transaction_id": models.TransactionPictureNewPictureTransactionId}))
sess.And(builder.Or(builder.In("transaction_id", subQuery), builder.In("related_id", subQuery)))
return sess
}
func (s *TransactionService) isAccountIdValid(transaction *models.Transaction) error {
if transaction.Type == models.TRANSACTION_DB_TYPE_MODIFY_BALANCE {
if transaction.RelatedAccountId != 0 && transaction.RelatedAccountId != transaction.AccountId {