add stats api impl
This commit is contained in:
parent
16155985ac
commit
47c21de613
|
|
@ -16,7 +16,8 @@ type QueryParams struct {
|
||||||
Month int `bql:"month ="`
|
Month int `bql:"month ="`
|
||||||
Tag string `bql:"in tags"`
|
Tag string `bql:"in tags"`
|
||||||
Account string `bql:"account ="`
|
Account string `bql:"account ="`
|
||||||
AccountType string `bql:"account ~"`
|
AccountLike string `bql:"account ~"`
|
||||||
|
GroupBy string `bql:"group by"`
|
||||||
OrderBy string `bql:"order by"`
|
OrderBy string `bql:"order by"`
|
||||||
Limit int `bql:"limit"`
|
Limit int `bql:"limit"`
|
||||||
Path string
|
Path string
|
||||||
|
|
@ -44,7 +45,7 @@ func GetQueryParams(c *gin.Context) QueryParams {
|
||||||
hasWhere = true
|
hasWhere = true
|
||||||
}
|
}
|
||||||
if c.Query("type") != "" {
|
if c.Query("type") != "" {
|
||||||
queryParams.AccountType = c.Query("type")
|
queryParams.AccountLike = c.Query("type")
|
||||||
hasWhere = true
|
hasWhere = true
|
||||||
}
|
}
|
||||||
if c.Query("account") != "" {
|
if c.Query("account") != "" {
|
||||||
|
|
@ -138,7 +139,7 @@ func bqlRawQuery(ledgerConfig *Config, selectBql string, queryParamsPtr *QueryPa
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
val := valueField.String()
|
val := valueField.String()
|
||||||
if val != "" {
|
if val != "" {
|
||||||
if typeField.Name == "OrderBy" {
|
if typeField.Name == "OrderBy" || typeField.Name == "GroupBy" {
|
||||||
// 去除上一个条件后缀的 AND 关键字
|
// 去除上一个条件后缀的 AND 关键字
|
||||||
bql = strings.Trim(bql, " AND")
|
bql = strings.Trim(bql, " AND")
|
||||||
bql = fmt.Sprintf("%s %s %s", bql, typeField.Tag.Get("bql"), val)
|
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("/account/type", service.QueryAccountType)
|
||||||
authorized.GET("/stats/months", service.MonthsList)
|
authorized.GET("/stats/months", service.MonthsList)
|
||||||
authorized.GET("/stats/total", service.StatsTotal)
|
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", service.QueryTransactions)
|
||||||
authorized.GET("/transaction/payee", service.QueryTransactionPayees)
|
authorized.GET("/transaction/payee", service.QueryTransactionPayees)
|
||||||
authorized.GET("/transaction/template", service.QueryTransactionTemplates)
|
authorized.GET("/transaction/template", service.QueryTransactionTemplates)
|
||||||
|
|
|
||||||
110
service/stats.go
110
service/stats.go
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/beancount-gs/script"
|
"github.com/beancount-gs/script"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -27,16 +28,16 @@ func MonthsList(c *gin.Context) {
|
||||||
OK(c, months)
|
OK(c, months)
|
||||||
}
|
}
|
||||||
|
|
||||||
type statsAccountTypeTotal struct {
|
type StatsResult struct {
|
||||||
AccountType string
|
Key string
|
||||||
Amount string
|
Value string
|
||||||
}
|
}
|
||||||
|
|
||||||
func StatsTotal(c *gin.Context) {
|
func StatsTotal(c *gin.Context) {
|
||||||
ledgerConfig := script.GetLedgerConfigFromContext(c)
|
ledgerConfig := script.GetLedgerConfigFromContext(c)
|
||||||
queryParams := script.GetQueryParams(c)
|
queryParams := script.GetQueryParams(c)
|
||||||
selectBql := fmt.Sprintf("SELECT '\\', root(account, 1), '\\', sum(convert(value(position), '%s')), '\\'", ledgerConfig.OperatingCurrency)
|
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)
|
err := script.BQLQueryListByCustomSelect(ledgerConfig, selectBql, &queryParams, &accountTypeTotalList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
InternalError(c, err.Error())
|
InternalError(c, err.Error())
|
||||||
|
|
@ -45,11 +46,108 @@ func StatsTotal(c *gin.Context) {
|
||||||
|
|
||||||
result := make(map[string]string, 0)
|
result := make(map[string]string, 0)
|
||||||
for _, total := range accountTypeTotalList {
|
for _, total := range accountTypeTotalList {
|
||||||
fields := strings.Fields(total.Amount)
|
fields := strings.Fields(total.Value)
|
||||||
if len(fields) > 1 {
|
if len(fields) > 1 {
|
||||||
result[total.AccountType] = fields[0]
|
result[total.Key] = fields[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OK(c, result)
|
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