add stats api impl
This commit is contained in:
parent
16155985ac
commit
47c21de613
|
|
@ -16,7 +16,8 @@ type QueryParams struct {
|
|||
Month int `bql:"month ="`
|
||||
Tag string `bql:"in tags"`
|
||||
Account string `bql:"account ="`
|
||||
AccountType string `bql:"account ~"`
|
||||
AccountLike string `bql:"account ~"`
|
||||
GroupBy string `bql:"group by"`
|
||||
OrderBy string `bql:"order by"`
|
||||
Limit int `bql:"limit"`
|
||||
Path string
|
||||
|
|
@ -44,7 +45,7 @@ func GetQueryParams(c *gin.Context) QueryParams {
|
|||
hasWhere = true
|
||||
}
|
||||
if c.Query("type") != "" {
|
||||
queryParams.AccountType = c.Query("type")
|
||||
queryParams.AccountLike = c.Query("type")
|
||||
hasWhere = true
|
||||
}
|
||||
if c.Query("account") != "" {
|
||||
|
|
@ -138,7 +139,7 @@ func bqlRawQuery(ledgerConfig *Config, selectBql string, queryParamsPtr *QueryPa
|
|||
case reflect.String:
|
||||
val := valueField.String()
|
||||
if val != "" {
|
||||
if typeField.Name == "OrderBy" {
|
||||
if typeField.Name == "OrderBy" || typeField.Name == "GroupBy" {
|
||||
// 去除上一个条件后缀的 AND 关键字
|
||||
bql = strings.Trim(bql, " AND")
|
||||
bql = fmt.Sprintf("%s %s %s", bql, typeField.Tag.Get("bql"), val)
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ func RegisterRouter(router *gin.Engine) {
|
|||
authorized.GET("/account/type", service.QueryAccountType)
|
||||
authorized.GET("/stats/months", service.MonthsList)
|
||||
authorized.GET("/stats/total", service.StatsTotal)
|
||||
authorized.GET("/stats/account/percent", service.StatsAccountPercent)
|
||||
authorized.GET("/stats/account/trend", service.StatsAccountTrend)
|
||||
authorized.GET("/transaction", service.QueryTransactions)
|
||||
authorized.GET("/transaction/payee", service.QueryTransactionPayees)
|
||||
authorized.GET("/transaction/template", service.QueryTransactionTemplates)
|
||||
|
|
|
|||
110
service/stats.go
110
service/stats.go
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/beancount-gs/script"
|
||||
"github.com/gin-gonic/gin"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
|
@ -27,16 +28,16 @@ func MonthsList(c *gin.Context) {
|
|||
OK(c, months)
|
||||
}
|
||||
|
||||
type statsAccountTypeTotal struct {
|
||||
AccountType string
|
||||
Amount string
|
||||
type StatsResult struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
func StatsTotal(c *gin.Context) {
|
||||
ledgerConfig := script.GetLedgerConfigFromContext(c)
|
||||
queryParams := script.GetQueryParams(c)
|
||||
selectBql := fmt.Sprintf("SELECT '\\', root(account, 1), '\\', sum(convert(value(position), '%s')), '\\'", ledgerConfig.OperatingCurrency)
|
||||
accountTypeTotalList := make([]statsAccountTypeTotal, 0)
|
||||
accountTypeTotalList := make([]StatsResult, 0)
|
||||
err := script.BQLQueryListByCustomSelect(ledgerConfig, selectBql, &queryParams, &accountTypeTotalList)
|
||||
if err != nil {
|
||||
InternalError(c, err.Error())
|
||||
|
|
@ -45,11 +46,108 @@ func StatsTotal(c *gin.Context) {
|
|||
|
||||
result := make(map[string]string, 0)
|
||||
for _, total := range accountTypeTotalList {
|
||||
fields := strings.Fields(total.Amount)
|
||||
fields := strings.Fields(total.Value)
|
||||
if len(fields) > 1 {
|
||||
result[total.AccountType] = fields[0]
|
||||
result[total.Key] = fields[0]
|
||||
}
|
||||
}
|
||||
|
||||
OK(c, result)
|
||||
}
|
||||
|
||||
type StatsQuery struct {
|
||||
Prefix string `form:"prefix" binding:"required"`
|
||||
Year int `form:"year"`
|
||||
Month int `form:"month"`
|
||||
Level int `form:"level"`
|
||||
Type string `form:"type"`
|
||||
}
|
||||
|
||||
type AccountPercentResult struct {
|
||||
Account string `json:"account"`
|
||||
Amount string `json:"amount"`
|
||||
OperatingCurrency string `json:"operatingCurrency"`
|
||||
}
|
||||
|
||||
func StatsAccountPercent(c *gin.Context) {
|
||||
ledgerConfig := script.GetLedgerConfigFromContext(c)
|
||||
var statsQuery StatsQuery
|
||||
if err := c.ShouldBindQuery(&statsQuery); err != nil {
|
||||
BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
queryParams := script.QueryParams{
|
||||
AccountLike: statsQuery.Prefix,
|
||||
Year: statsQuery.Year,
|
||||
Month: statsQuery.Month,
|
||||
Where: true,
|
||||
}
|
||||
var bql string
|
||||
if statsQuery.Level != 0 {
|
||||
prefixNodeLen := len(strings.Split(strings.Trim(statsQuery.Prefix, ":"), ":"))
|
||||
bql = fmt.Sprintf("SELECT '\\', root(account, %d) as subAccount, '\\', sum(convert(value(position), '%s')), '\\'", statsQuery.Level+prefixNodeLen, ledgerConfig.OperatingCurrency)
|
||||
} else {
|
||||
bql = fmt.Sprintf("SELECT '\\', account, '\\', sum(convert(value(position), '%s')), '\\'", ledgerConfig.OperatingCurrency)
|
||||
}
|
||||
|
||||
statsResultList := make([]AccountPercentResult, 0)
|
||||
err := script.BQLQueryListByCustomSelect(ledgerConfig, bql, &queryParams, &statsResultList)
|
||||
if err != nil {
|
||||
InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
for idx, result := range statsResultList {
|
||||
fields := strings.Fields(result.Amount)
|
||||
statsResultList[idx].Amount = fields[0]
|
||||
statsResultList[idx].OperatingCurrency = fields[1]
|
||||
}
|
||||
OK(c, statsResultList)
|
||||
}
|
||||
|
||||
type AccountTrendResult struct {
|
||||
Date string `json:"date"`
|
||||
Amount float64 `json:"amount"`
|
||||
OperatingCurrency string `json:"operatingCurrency"`
|
||||
}
|
||||
|
||||
func StatsAccountTrend(c *gin.Context) {
|
||||
ledgerConfig := script.GetLedgerConfigFromContext(c)
|
||||
var statsQuery StatsQuery
|
||||
if err := c.ShouldBindQuery(&statsQuery); err != nil {
|
||||
BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
queryParams := script.QueryParams{
|
||||
AccountLike: statsQuery.Prefix,
|
||||
Year: statsQuery.Year,
|
||||
Month: statsQuery.Month,
|
||||
Where: true,
|
||||
}
|
||||
var bql string
|
||||
if statsQuery.Type == "avg" {
|
||||
bql = fmt.Sprintf("SELECT '\\', date, '\\', sum(convert(value(position), '%s')), '\\'", ledgerConfig.OperatingCurrency)
|
||||
} else if statsQuery.Type == "sum" {
|
||||
bql = fmt.Sprintf("SELECT '\\', date, '\\', convert(balance, '%s'), '\\'", ledgerConfig.OperatingCurrency)
|
||||
} else {
|
||||
OK(c, new([]string))
|
||||
return
|
||||
}
|
||||
|
||||
statsResultList := make([]StatsResult, 0)
|
||||
err := script.BQLQueryListByCustomSelect(ledgerConfig, bql, &queryParams, &statsResultList)
|
||||
if err != nil {
|
||||
InternalError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
result := make([]AccountTrendResult, 0)
|
||||
for _, stats := range statsResultList {
|
||||
fields := strings.Fields(stats.Value)
|
||||
amount, _ := strconv.ParseFloat(fields[0], 32)
|
||||
result = append(result, AccountTrendResult{Date: stats.Key, Amount: amount, OperatingCurrency: fields[1]})
|
||||
}
|
||||
OK(c, result)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue