package db import ( "context" ) type ListExpenseConditionParam struct { TimeBegin string TimeEnd string ProjectID int64 BudgetID int64 ExpenseType int32 IsTitle bool Title string Status int16 PageID int32 PageSize int32 } type ExpenseView struct { Expense ProjectName string `json:"project_name"` BudgetName string `json:"budget_name"` ExpensesTypeName string `json:"expenses_type_name"` CreatedName string `json:"created_name"` UpdatedName string `json:"updated_name"` } func (store *SQLStore) ListExpenseCondition(ctx context.Context, arg *ListExpenseConditionParam) ([]*ExpenseView, int64, error) { query, args, err := BuildQuery(` SELECT COUNT(1) FROM expenses WHERE created_at BETWEEN @start AND @end {{if ne .status 9999}}AND status = @status{{end}} {{if ne .projecID 9999}}AND project_id = @projecID{{end}} {{if ne .budgetID 9999}}AND budget_id = @budgetID{{end}} {{if ne .expensesType 9999}}AND expenses_type = @expensesType{{end}} {{if .isTitle}}AND name LIKE @title{{end}}; `, map[string]any{ "projecID": arg.ProjectID, "budgetID": arg.BudgetID, "expensesType": arg.ExpenseType, "start": arg.TimeBegin, "end": arg.TimeEnd, "status": arg.Status, "isTitle": arg.IsTitle, "title": arg.Title, }) if err != nil { return nil, 0, err } var total int64 if err := store.db.QueryRow(ctx, query, args...).Scan(&total); err != nil { return nil, 0, err } if total <= 0 { return nil, 0, nil } query, args, err = BuildQuery(` select id, project_id, COALESCE((SELECT name FROM projects WHERE id = expenses.project_id), '') as project_name, budget_id, COALESCE((SELECT name FROM budgets WHERE id = expenses.budget_id), '') as budget_name, amount, expenses_at, expenses_type, COALESCE((SELECT name FROM categories WHERE id = expenses.expenses_type), '') as expense_type_name, remark, status, created_at, created_user_id, COALESCE((SELECT username FROM sys_user WHERE id = expenses.created_user_id), '') as created_name, updated_at, updated_user_id, COALESCE((SELECT username FROM sys_user WHERE id = expenses.updated_user_id), '') as updated_name FROM expenses WHERE created_at BETWEEN @start AND @end {{if ne .status 9999}}AND status = @status{{end}} {{if ne .projecID 9999}}AND project_id = @projecID{{end}} {{if ne .budgetID 9999}}AND budget_id = @budgetID{{end}} {{if ne .expensesType 9999}}AND expenses_type = @expensesType{{end}} {{if .isTitle}}AND name LIKE @title{{end}} ORDER BY id DESC LIMIT @limit OFFSET @offset; `, map[string]any{ "projecID": arg.ProjectID, "budgetID": arg.BudgetID, "expensesType": arg.ExpenseType, "start": arg.TimeBegin, "end": arg.TimeEnd, "status": arg.Status, "isTitle": arg.IsTitle, "title": arg.Title, "limit": arg.PageSize, "offset": (arg.PageID - 1) * arg.PageSize, }) if err != nil { return nil, 0, err } rows, err := store.db.Query(ctx, query, args...) if err != nil { return nil, 0, err } defer rows.Close() items := []*ExpenseView{} for rows.Next() { var i ExpenseView if err := rows.Scan( &i.ID, &i.ProjectID, &i.ProjectName, &i.BudgetID, &i.BudgetName, &i.Amount, &i.ExpensesAt, &i.ExpensesType, &i.ExpensesTypeName, &i.Remark, &i.Status, &i.CreatedAt, &i.CreatedUserID, &i.CreatedName, &i.UpdatedAt, &i.UpdatedUserID, &i.UpdatedName, ); err != nil { return nil, 0, err } items = append(items, &i) } if err := rows.Err(); err != nil { return nil, 0, err } return items, total, nil }