add event api

This commit is contained in:
BaoXuebin 2023-12-06 00:29:38 +08:00
parent 727d504f2f
commit 4ffe60112c
10 changed files with 150 additions and 9 deletions

View File

@ -25,7 +25,7 @@
- [X] 投资管理(FIFO)
- [X] 第三方账单导入(支付宝,微信,工商银行,农业银行)
- [X] 分期记账
- [ ] 事件
- [X] 事件
## 如何使用

View File

@ -113,6 +113,15 @@ func BeanReportAllPrices(ledgerConfig *Config) string {
return string(output)
}
func BeanReportAllEvents(ledgerConfig *Config) string {
beanFilePath := GetLedgerEventsFilePath(ledgerConfig.DataPath)
LogInfo(ledgerConfig.Mail, "bean-report "+beanFilePath+" events")
cmd := exec.Command("bean-report", beanFilePath, "events")
output, _ := cmd.Output()
return string(output)
}
func bqlRawQuery(ledgerConfig *Config, selectBql string, queryParamsPtr *QueryParams, queryResultPtr interface{}) (string, error) {
var bql string
if selectBql == "" {

View File

@ -1,9 +1,11 @@
package script
import (
"bufio"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
func FileIfExist(filePath string) bool {
@ -59,6 +61,60 @@ func AppendFileInNewLine(filePath string, content string) error {
return err
}
func DeleteLinesWithText(filePath string, textToDelete string) error {
// 打开文件以供读写
file, err := os.OpenFile(filePath, os.O_RDWR, 0644)
if err != nil {
return err
}
defer file.Close()
// 创建一个缓冲读取器
scanner := bufio.NewScanner(file)
// 创建一个字符串切片,用于保存文件的每一行
var lines []string
// 逐行读取文件内容
for scanner.Scan() {
line := scanner.Text()
// 检查行是否包含要删除的文本
if !strings.Contains(line, textToDelete) {
lines = append(lines, line)
}
}
// 关闭文件
file.Close()
// 重新打开文件以供写入
file, err = os.OpenFile(filePath, os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer file.Close()
// 创建一个写入器
writer := bufio.NewWriter(file)
// 将修改后的内容写回文件
for _, line := range lines {
_, err := writer.WriteString(line + "\n")
if err != nil {
return err
}
}
// 刷新缓冲区,确保所有数据被写入文件
err = writer.Flush()
if err != nil {
return err
}
return nil
}
func CreateFile(filePath string) error {
if _, e := os.Stat(filePath); os.IsNotExist(e) {
_ = os.MkdirAll(filepath.Dir(filePath), os.ModePerm)

View File

@ -56,3 +56,13 @@ func GetLedgerIndexFilePath(dataPath string) string {
LogInfo(dataPath, dataPath+"/index.bean")
return dataPath + "/index.bean"
}
func GetLedgerIncludesFilePath(dataPath string) string {
LogInfo(dataPath, dataPath+"/includes.bean")
return dataPath + "/includes.bean"
}
func GetLedgerEventsFilePath(dataPath string) string {
LogInfo(dataPath, dataPath+"/event/events.bean")
return dataPath + "/event/events.bean"
}

View File

@ -6,6 +6,7 @@ import (
)
func isWindows() bool {
return false
os := runtime.GOOS
return os == "windows"
}

View File

@ -84,8 +84,9 @@ func RegisterRouter(router *gin.Engine) {
authorized.GET("/transaction/template", service.QueryTransactionTemplates)
authorized.POST("/transaction/template", service.AddTransactionTemplate)
authorized.DELETE("/transaction/template", service.DeleteTransactionTemplate)
authorized.GET("/event/page", service.GetAllEvents)
authorized.GET("/event/all", service.GetAllEvents)
authorized.POST("/event", service.AddEvent)
authorized.DELETE("/event", service.DeleteEvent)
authorized.GET("/tags", service.QueryTags)
authorized.GET("/file/dir", service.QueryLedgerSourceFileDir)
authorized.GET("/file/content", service.QueryLedgerSourceFileContent)

View File

@ -32,7 +32,7 @@ type accountPosition struct {
func QueryAllAccount(c *gin.Context) {
ledgerConfig := script.GetLedgerConfigFromContext(c)
bql := fmt.Sprintf("select '\\', account, '\\', sum(convert(value(position), '%s')) as market_position, '\\', sum(value(position)) as position, '\\'", ledgerConfig.OperatingCurrency)
bql := fmt.Sprintf("select '\\', account, '\\', sum(convert(value(position), '%s')) as market_position, '\\', sum(convert(value(position), currency)) as position, '\\'", ledgerConfig.OperatingCurrency)
accountPositions := make([]accountPosition, 0)
err := script.BQLQueryListByCustomSelect(ledgerConfig, bql, nil, &accountPositions)
if err != nil {

View File

@ -1,17 +1,79 @@
package service
import "github.com/gin-gonic/gin"
import (
"fmt"
"github.com/beancount-gs/script"
"github.com/gin-gonic/gin"
"strings"
)
type Event struct {
Date string `json:"date"`
Type string `json:"type"`
Description string `json:"description"`
Date string `form:"date" binding:"required" json:"date"`
Type string `form:"type" binding:"required" json:"type"`
Description string `form:"description" binding:"required" json:"description"`
}
func GetAllEvents(c *gin.Context) {
OK(c, nil)
ledgerConfig := script.GetLedgerConfigFromContext(c)
output := script.BeanReportAllEvents(ledgerConfig)
script.LogInfo(ledgerConfig.Mail, output)
events := make([]Event, 0)
lines := strings.Split(output, "\n")
// foreach lines
for idx, line := range lines {
if idx < 2 || idx > len(lines)-3 {
continue
}
if strings.Trim(line, " ") == "" {
continue
}
// split line by " "
words := strings.Fields(line)
events = append(events, Event{
Date: words[0],
Type: words[1],
Description: words[2],
})
}
OK(c, events)
}
func AddEvent(c *gin.Context) {
var event Event
if err := c.ShouldBindJSON(&event); err != nil {
BadRequest(c, err.Error())
return
}
ledgerConfig := script.GetLedgerConfigFromContext(c)
filePath := script.GetLedgerEventsFilePath(ledgerConfig.DataPath)
line := fmt.Sprintf("%s event \"%s\" \"%s\"", event.Date, event.Type, event.Description)
// 写入文件
err := script.AppendFileInNewLine(filePath, line)
if err != nil {
InternalError(c, err.Error())
return
}
OK(c, event)
}
func DeleteEvent(c *gin.Context) {
var event Event
if err := c.ShouldBindJSON(&event); err != nil {
BadRequest(c, err.Error())
return
}
ledgerConfig := script.GetLedgerConfigFromContext(c)
filePath := script.GetLedgerEventsFilePath(ledgerConfig.DataPath)
line := fmt.Sprintf("%s event \"%s\" \"%s\"", event.Date, event.Type, event.Description)
err := script.DeleteLinesWithText(filePath, line)
if err != nil {
InternalError(c, err.Error())
return
}
OK(c, nil)
}

View File

View File

@ -9,4 +9,6 @@ include "./price/prices.bean"
; 历史数据(用于 导入 之前的数据)
include "./history.bean"
; 新的数据(按月拆分)
include "./month/months.bean"
include "./month/months.bean"
; 事件数据
include "./event/events.bean"