add: account api impl
This commit is contained in:
parent
4d25e8dc9e
commit
a5a3365997
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -44,20 +44,6 @@ func GetQueryParams(c *gin.Context) QueryParams {
|
||||||
return queryParams
|
return queryParams
|
||||||
}
|
}
|
||||||
|
|
||||||
func BQLReport(ledgerConfig *Config, ledgerAccounts *[]Account) error {
|
|
||||||
beanFilePath := ledgerConfig.DataPath + "/index.bean"
|
|
||||||
cmd := exec.Command("bean-report", beanFilePath, "accounts")
|
|
||||||
output, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println(string(output))
|
|
||||||
|
|
||||||
//json.Unmarshal(ledgerAccounts)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func BQLQueryOne(ledgerConfig *Config, queryParams *QueryParams, queryResultPtr interface{}) error {
|
func BQLQueryOne(ledgerConfig *Config, queryParams *QueryParams, queryResultPtr interface{}) error {
|
||||||
assertQueryResultIsPointer(queryResultPtr)
|
assertQueryResultIsPointer(queryResultPtr)
|
||||||
output, err := bqlRawQuery(ledgerConfig, "", queryParams, queryResultPtr)
|
output, err := bqlRawQuery(ledgerConfig, "", queryParams, queryResultPtr)
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,15 @@ package script
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var serverConfig Config
|
var serverConfig Config
|
||||||
var ledgerConfigMap map[string]Config
|
var ledgerConfigMap map[string]Config
|
||||||
var ledgerAccountsMap map[string][]Account
|
var ledgerAccountsMap map[string][]Account
|
||||||
|
var ledgerAccountTypesMap map[string]map[string]string
|
||||||
var whiteList []string
|
var whiteList []string
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
|
@ -21,13 +25,13 @@ type Config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Account struct {
|
type Account struct {
|
||||||
Acc string `json:"account"`
|
Acc string `json:"account"`
|
||||||
Commodity string `json:"commodity"`
|
Commodity string `json:"commodity"`
|
||||||
StartDate string `json:"startDate"`
|
StartDate string `json:"startDate"`
|
||||||
Type accountType `json:"type"`
|
EndDate string `json:"endDate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type accountType struct {
|
type AccountType struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +72,10 @@ func GetLedgerAccounts(ledgerId string) []Account {
|
||||||
return ledgerAccountsMap[ledgerId]
|
return ledgerAccountsMap[ledgerId]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetLedgerAccountTypes(ledgerId string) map[string]string {
|
||||||
|
return ledgerAccountTypesMap[ledgerId]
|
||||||
|
}
|
||||||
|
|
||||||
func IsInWhiteList(ledgerId string) bool {
|
func IsInWhiteList(ledgerId string) bool {
|
||||||
// ledger white list is empty, return true
|
// ledger white list is empty, return true
|
||||||
if whiteList == nil || len(whiteList) == 0 {
|
if whiteList == nil || len(whiteList) == 0 {
|
||||||
|
|
@ -122,17 +130,87 @@ func LoadLedgerConfigMap() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadLedgerAccountsMap() error {
|
func LoadLedgerAccountsMap() error {
|
||||||
|
if ledgerAccountsMap == nil {
|
||||||
|
ledgerAccountsMap = make(map[string][]Account)
|
||||||
|
}
|
||||||
for _, config := range ledgerConfigMap {
|
for _, config := range ledgerConfigMap {
|
||||||
accounts := make([]Account, 0)
|
// 加载 account_type.json 到缓存(内存)
|
||||||
err := BQLReport(&config, &accounts)
|
loadErr := LoadLedgerAccountTypesMap(config)
|
||||||
|
if loadErr != nil {
|
||||||
|
LogSystemError("Failed to load account types")
|
||||||
|
return loadErr
|
||||||
|
}
|
||||||
|
accountDirPath := config.DataPath + "/account"
|
||||||
|
dirs, err := os.ReadDir(accountDirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//ledgerAccountsMap[ledgerId] = accounts
|
accountMap := make(map[string]Account)
|
||||||
|
for _, dir := range dirs {
|
||||||
|
bytes, err := ReadFile(accountDirPath + "/" + dir.Name())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lines := strings.Split(string(bytes), "\n")
|
||||||
|
var temp Account
|
||||||
|
for _, line := range lines {
|
||||||
|
if line != "" {
|
||||||
|
words := strings.Fields(line)
|
||||||
|
if len(words) >= 3 {
|
||||||
|
key := words[2]
|
||||||
|
temp = accountMap[key]
|
||||||
|
account := Account{Acc: key}
|
||||||
|
// 货币单位
|
||||||
|
if len(words) >= 4 {
|
||||||
|
account.Commodity = words[3]
|
||||||
|
}
|
||||||
|
if words[1] == "open" {
|
||||||
|
account.StartDate = words[0]
|
||||||
|
} else if words[1] == "close" {
|
||||||
|
account.EndDate = words[0]
|
||||||
|
}
|
||||||
|
if temp.StartDate != "" {
|
||||||
|
account.StartDate = temp.StartDate
|
||||||
|
}
|
||||||
|
if temp.EndDate != "" {
|
||||||
|
account.EndDate = temp.EndDate
|
||||||
|
}
|
||||||
|
accountMap[key] = account
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accounts := make([]Account, 0)
|
||||||
|
for _, account := range accountMap {
|
||||||
|
accounts = append(accounts, account)
|
||||||
|
}
|
||||||
|
// 账户按字母排序
|
||||||
|
sort.Sort(AccountSort(accounts))
|
||||||
|
ledgerAccountsMap[config.Id] = accounts
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadLedgerAccountTypesMap(config Config) error {
|
||||||
|
path := GetLedgerAccountTypeFilePath(config.DataPath)
|
||||||
|
fileContent, err := ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
accountTypes := make(map[string]string)
|
||||||
|
err = json.Unmarshal(fileContent, &accountTypes)
|
||||||
|
if err != nil {
|
||||||
|
LogSystemError("Failed unmarshal config file (" + path + ")")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ledgerAccountTypesMap == nil {
|
||||||
|
ledgerAccountTypesMap = make(map[string]map[string]string)
|
||||||
|
}
|
||||||
|
ledgerAccountTypesMap[config.Id] = accountTypes
|
||||||
|
LogSystemInfo("Success load ledger_config file (" + path + ")")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func WriteLedgerConfigMap(newLedgerConfigMap map[string]Config) error {
|
func WriteLedgerConfigMap(newLedgerConfigMap map[string]Config) error {
|
||||||
path := GetServerLedgerConfigFilePath()
|
path := GetServerLedgerConfigFilePath()
|
||||||
mapBytes, err := json.Marshal(ledgerConfigMap)
|
mapBytes, err := json.Marshal(ledgerConfigMap)
|
||||||
|
|
|
||||||
|
|
@ -17,3 +17,7 @@ func GetExampleLedgerConfigDirPath() string {
|
||||||
func GetLedgerTransactionsTemplateFilePath(dataPath string) string {
|
func GetLedgerTransactionsTemplateFilePath(dataPath string) string {
|
||||||
return dataPath + "/.beancount-ns/transaction_template.json"
|
return dataPath + "/.beancount-ns/transaction_template.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetLedgerAccountTypeFilePath(dataPath string) string {
|
||||||
|
return dataPath + "/.beancount-ns/account_type.json"
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package script
|
||||||
|
|
||||||
|
type AccountTypeSort []AccountType
|
||||||
|
type AccountSort []Account
|
||||||
|
|
||||||
|
func (s AccountTypeSort) Len() int {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s AccountTypeSort) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s AccountTypeSort) Less(i, j int) bool {
|
||||||
|
return s[i].Key <= s[j].Key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s AccountSort) Len() int {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s AccountSort) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s AccountSort) Less(i, j int) bool {
|
||||||
|
return s[i].Acc <= s[j].Acc
|
||||||
|
}
|
||||||
|
|
@ -49,6 +49,8 @@ func RegisterRouter(router *gin.Engine) {
|
||||||
authorized.Use(AuthorizedHandler())
|
authorized.Use(AuthorizedHandler())
|
||||||
{
|
{
|
||||||
// need authorized
|
// need authorized
|
||||||
|
authorized.GET("/account/valid", service.QueryValidAccount)
|
||||||
|
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("/transactions", service.QueryTransactions)
|
authorized.GET("/transactions", service.QueryTransactions)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,24 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import "github.com/gin-gonic/gin"
|
import (
|
||||||
|
"github.com/beancount-gs/script"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
func QueryValidAccount(c *gin.Context) {
|
func QueryValidAccount(c *gin.Context) {
|
||||||
|
ledgerConfig := script.GetLedgerConfigFromContext(c)
|
||||||
|
OK(c, script.GetLedgerAccounts(ledgerConfig.Id))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
func QueryAccountType(c *gin.Context) {
|
||||||
|
ledgerConfig := script.GetLedgerConfigFromContext(c)
|
||||||
|
accountTypes := script.GetLedgerAccountTypes(ledgerConfig.Id)
|
||||||
|
|
||||||
|
result := make([]script.AccountType, 0)
|
||||||
|
for k, v := range accountTypes {
|
||||||
|
result = append(result, script.AccountType{Key: k, Name: v})
|
||||||
|
}
|
||||||
|
sort.Sort(script.AccountTypeSort(result))
|
||||||
|
OK(c, result)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue