From a5a3365997406ef8a0dfa2b616627d3d9bb61b7a Mon Sep 17 00:00:00 2001 From: BaoXuebin Date: Tue, 23 Nov 2021 14:58:37 +0800 Subject: [PATCH] add: account api impl --- favicon.ico | Bin 0 -> 1165 bytes script/bql.go | 14 ------- script/config.go | 94 ++++++++++++++++++++++++++++++++++++++++---- script/paths.go | 4 ++ script/sort.go | 28 +++++++++++++ server.go | 2 + service/accounts.go | 21 +++++++++- 7 files changed, 139 insertions(+), 24 deletions(-) create mode 100644 favicon.ico create mode 100644 script/sort.go diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f73a6800ad6aa634e08ba41e1278f9fd83badf71 GIT binary patch literal 1165 zcmV;81akWT0096203aX$0096P0Cxlc02TlM0EtjeM-2)Z3IG5A4M|8uQUCw|AOHXW zAP5Ek0047(dh`GQ00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E000SaNLh0L01m?d z01m?e$8V@)000CGNklE)L6$Dp;kKsabAtNY?S=^0j*pMk_-faP#E1ysPrpC{CHy1o z4=)F>84A#V*8MQX%FD|m0yi~=hljOvrUD81WzZ7Xd9(=#0lJiiVnazu$$xkf^GvQgBL)(j*6- z8yg#w>FH?!$i9s1hQtYH#%r`B($mueaFXOR06f>%*QebMiMhGCFKYOTP{(LUPzJ7j zVgk&kAW6H5iVA@QN=!{n1!~y0BJbG5S5q_u*b4@r7zs~KPKv9ntd#EVZW$aLl#!7U zb()x%P%Fn%O>*?u<8XPhm9UTfr%g(&3NONGdB$;-==+}vEr$;r_*ha&-a+V5Bp@MHWG*Totv f(s;iFeiirwh|l=}BwD=100000NkvXXu0mjf!Z97J literal 0 HcmV?d00001 diff --git a/script/bql.go b/script/bql.go index 24db2c3..8e10ae5 100644 --- a/script/bql.go +++ b/script/bql.go @@ -44,20 +44,6 @@ func GetQueryParams(c *gin.Context) 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 { assertQueryResultIsPointer(queryResultPtr) output, err := bqlRawQuery(ledgerConfig, "", queryParams, queryResultPtr) diff --git a/script/config.go b/script/config.go index 355fad2..6e37656 100644 --- a/script/config.go +++ b/script/config.go @@ -3,11 +3,15 @@ package script import ( "encoding/json" "github.com/gin-gonic/gin" + "os" + "sort" + "strings" ) var serverConfig Config var ledgerConfigMap map[string]Config var ledgerAccountsMap map[string][]Account +var ledgerAccountTypesMap map[string]map[string]string var whiteList []string type Config struct { @@ -21,13 +25,13 @@ type Config struct { } type Account struct { - Acc string `json:"account"` - Commodity string `json:"commodity"` - StartDate string `json:"startDate"` - Type accountType `json:"type"` + Acc string `json:"account"` + Commodity string `json:"commodity"` + StartDate string `json:"startDate"` + EndDate string `json:"endDate"` } -type accountType struct { +type AccountType struct { Key string `json:"key"` Name string `json:"name"` } @@ -68,6 +72,10 @@ func GetLedgerAccounts(ledgerId string) []Account { return ledgerAccountsMap[ledgerId] } +func GetLedgerAccountTypes(ledgerId string) map[string]string { + return ledgerAccountTypesMap[ledgerId] +} + func IsInWhiteList(ledgerId string) bool { // ledger white list is empty, return true if whiteList == nil || len(whiteList) == 0 { @@ -122,17 +130,87 @@ func LoadLedgerConfigMap() error { } func LoadLedgerAccountsMap() error { + if ledgerAccountsMap == nil { + ledgerAccountsMap = make(map[string][]Account) + } for _, config := range ledgerConfigMap { - accounts := make([]Account, 0) - err := BQLReport(&config, &accounts) + // 加载 account_type.json 到缓存(内存) + 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 { 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 } +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 { path := GetServerLedgerConfigFilePath() mapBytes, err := json.Marshal(ledgerConfigMap) diff --git a/script/paths.go b/script/paths.go index 88ac947..8bec7ee 100644 --- a/script/paths.go +++ b/script/paths.go @@ -17,3 +17,7 @@ func GetExampleLedgerConfigDirPath() string { func GetLedgerTransactionsTemplateFilePath(dataPath string) string { return dataPath + "/.beancount-ns/transaction_template.json" } + +func GetLedgerAccountTypeFilePath(dataPath string) string { + return dataPath + "/.beancount-ns/account_type.json" +} diff --git a/script/sort.go b/script/sort.go new file mode 100644 index 0000000..e19e218 --- /dev/null +++ b/script/sort.go @@ -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 +} diff --git a/server.go b/server.go index 718b010..1c84783 100644 --- a/server.go +++ b/server.go @@ -49,6 +49,8 @@ func RegisterRouter(router *gin.Engine) { authorized.Use(AuthorizedHandler()) { // need authorized + authorized.GET("/account/valid", service.QueryValidAccount) + authorized.GET("/account/type", service.QueryAccountType) authorized.GET("/stats/months", service.MonthsList) authorized.GET("/stats/total", service.StatsTotal) authorized.GET("/transactions", service.QueryTransactions) diff --git a/service/accounts.go b/service/accounts.go index e05b062..aef8f41 100644 --- a/service/accounts.go +++ b/service/accounts.go @@ -1,7 +1,24 @@ 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) { + ledgerConfig := script.GetLedgerConfigFromContext(c) + OK(c, script.GetLedgerAccounts(ledgerConfig.Id)) +} -} \ No newline at end of file +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) +}