...
|
...
|
@@ -4,6 +4,7 @@ import ( |
|
|
"fmt"
|
|
|
"github.com/go-gota/gota/dataframe"
|
|
|
"github.com/go-gota/gota/series"
|
|
|
"github.com/shopspring/decimal"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
|
|
|
"strings"
|
...
|
...
|
@@ -16,6 +17,17 @@ type Calculator struct { |
|
|
}
|
|
|
|
|
|
func NewCalculator(expr string) (*Calculator, error) {
|
|
|
ar, err := NewExprAST(expr)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
cal := &Calculator{
|
|
|
ExprAST: ar,
|
|
|
}
|
|
|
return cal, nil
|
|
|
}
|
|
|
|
|
|
func NewExprAST(expr string) (ExprAST, error) {
|
|
|
toks, err := ParseToken(expr)
|
|
|
if err != nil {
|
|
|
return nil, err
|
...
|
...
|
@@ -28,11 +40,7 @@ func NewCalculator(expr string) (*Calculator, error) { |
|
|
if ast.Err != nil {
|
|
|
return nil, ast.Err
|
|
|
}
|
|
|
|
|
|
cal := &Calculator{
|
|
|
ExprAST: ar,
|
|
|
}
|
|
|
return cal, nil
|
|
|
return ar, nil
|
|
|
}
|
|
|
|
|
|
func (cal *Calculator) SetDataTable(t *domain.DataTable) *Calculator {
|
...
|
...
|
@@ -106,19 +114,21 @@ func (cal *Calculator) callDef(name string, args []*param) *param { |
|
|
|
|
|
func (cal *Calculator) sum(params ...*param) *param {
|
|
|
var res = make([]string, 0)
|
|
|
var total float64
|
|
|
var total = decimal.NewFromFloat(0)
|
|
|
for _, p := range params {
|
|
|
for _, v := range p.data {
|
|
|
total += utils.NewNumberString(v).MustFloat64()
|
|
|
dv, _ := decimal.NewFromString(v)
|
|
|
total = total.Add(dv)
|
|
|
}
|
|
|
}
|
|
|
res = append(res, utils.AssertString(total))
|
|
|
res = append(res, total.String())
|
|
|
return NewResult(res)
|
|
|
}
|
|
|
|
|
|
func (cal *Calculator) sumifs(params ...*param) *param {
|
|
|
var list = make([]series.Series, 0)
|
|
|
var filters = make([]dataframe.F, 0)
|
|
|
var groupBy = make([]string, 0)
|
|
|
for i := 0; i < len(params)-1; i++ {
|
|
|
col := colName(i)
|
|
|
if i == 0 {
|
...
|
...
|
@@ -126,15 +136,27 @@ func (cal *Calculator) sumifs(params ...*param) *param { |
|
|
continue
|
|
|
}
|
|
|
if i%2 == 1 {
|
|
|
list = append(list, series.New(params[i+1].Data(), series.String, col))
|
|
|
if f, ok := cal.resolverFilter(col, params[i]); ok {
|
|
|
filters = append(filters, f)
|
|
|
list = append(list, series.New(params[i].Data(), series.String, col))
|
|
|
// TODO 类型是行字段判断为按行分组
|
|
|
if params[i+1].Len() > 1 {
|
|
|
groupBy = append(groupBy, col)
|
|
|
} else {
|
|
|
if f, ok := cal.resolverFilter(col, params[i+1]); ok {
|
|
|
filters = append(filters, f)
|
|
|
}
|
|
|
}
|
|
|
i++
|
|
|
}
|
|
|
}
|
|
|
df := dataframe.New(list...)
|
|
|
df = df.FilterAggregation(dataframe.And, filters...)
|
|
|
if len(groupBy) > 0 {
|
|
|
groups := df.GroupBy(groupBy...)
|
|
|
df = groups.Aggregation([]dataframe.AggregationType{dataframe.Aggregation_SUM}, []string{"A0"})
|
|
|
s := df.Col("A0_SUM")
|
|
|
return NewResult(toArrayFloat(s.Records())) //4000.00 需要格式化掉后缀 .00
|
|
|
}
|
|
|
|
|
|
s := df.Col("A0")
|
|
|
return NewResult(s.Records())
|
|
|
}
|
...
|
...
|
@@ -220,17 +242,21 @@ func (cal *Calculator) OpCalc(op string, lp *param, rp *param) *param { |
|
|
}
|
|
|
|
|
|
func opCalc(op, v1, v2 string) string {
|
|
|
fv1 := utils.NumberString(v1).MustFloat64()
|
|
|
fv2 := utils.NumberString(v2).MustFloat64()
|
|
|
//fv1 := utils.NumberString(v1).MustFloat64()
|
|
|
//fv2 := utils.NumberString(v2).MustFloat64()
|
|
|
|
|
|
fv1, _ := decimal.NewFromString(v1)
|
|
|
fv2, _ := decimal.NewFromString(v2)
|
|
|
switch op {
|
|
|
case "+":
|
|
|
return utils.AssertString(fv1 + fv2)
|
|
|
|
|
|
return utils.AssertString(fv1.Add(fv2).String())
|
|
|
case "-":
|
|
|
return utils.AssertString(fv1 - fv2)
|
|
|
return utils.AssertString(fv1.Sub(fv2).String()) // utils.Round(fv1-fv2, 15)
|
|
|
case "*":
|
|
|
return utils.AssertString(fv1 * fv2)
|
|
|
return utils.AssertString(fv1.Mul(fv2).String())
|
|
|
case "/":
|
|
|
return utils.AssertString(fv1 / fv2)
|
|
|
return utils.AssertString(fv1.Div(fv2).String())
|
|
|
}
|
|
|
return ""
|
|
|
}
|
...
|
...
|
@@ -252,3 +278,10 @@ func NewResult(data []string) *param { |
|
|
data: data,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func toArrayFloat(list []string) []string {
|
|
|
for i := range list {
|
|
|
list[i] = utils.AssertString(utils.NewNumberString(list[i]).MustFloat64())
|
|
|
}
|
|
|
return list
|
|
|
} |
...
|
...
|
|