正在显示
25 个修改的文件
包含
359 行增加
和
95 行删除
| @@ -16,7 +16,7 @@ import ( | @@ -16,7 +16,7 @@ import ( | ||
| 16 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/event" | 16 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/port/event" |
| 17 | ) | 17 | ) |
| 18 | 18 | ||
| 19 | -const Version = "v1.2.0" | 19 | +const Version = "v1.3.0" |
| 20 | 20 | ||
| 21 | func main() { | 21 | func main() { |
| 22 | defer func() { | 22 | defer func() { |
| @@ -20,11 +20,15 @@ type FileDto struct { | @@ -20,11 +20,15 @@ type FileDto struct { | ||
| 20 | Time string `json:"time"` | 20 | Time string `json:"time"` |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | -func (d *FileDto) Load(f *domain.File) { | 23 | +func (d *FileDto) Load(f *domain.File) *FileDto { |
| 24 | + if f == nil { | ||
| 25 | + return nil | ||
| 26 | + } | ||
| 24 | d.FileId = f.FileId | 27 | d.FileId = f.FileId |
| 25 | d.Name = f.FileInfo.Name | 28 | d.Name = f.FileInfo.Name |
| 26 | d.Url = f.FileInfo.Url | 29 | d.Url = f.FileInfo.Url |
| 27 | d.FileType = f.FileType | 30 | d.FileType = f.FileType |
| 28 | d.Ext = f.FileInfo.Ext | 31 | d.Ext = f.FileInfo.Ext |
| 29 | d.Time = xtime.New(f.UpdatedAt).Local().Format("2006-01-02 15:04:05") | 32 | d.Time = xtime.New(f.UpdatedAt).Local().Format("2006-01-02 15:04:05") |
| 33 | + return d | ||
| 30 | } | 34 | } |
| @@ -10,11 +10,15 @@ import ( | @@ -10,11 +10,15 @@ import ( | ||
| 10 | 10 | ||
| 11 | type GetFileQuery struct { | 11 | type GetFileQuery struct { |
| 12 | // 文件ID | 12 | // 文件ID |
| 13 | - FileId int `cname:"文件ID" json:"fileId" valid:"Required"` | 13 | + FileId int `cname:"文件ID" json:"fileId"` |
| 14 | + | ||
| 15 | + FileName string `json:"name"` | ||
| 16 | + | ||
| 17 | + FileType string `json:"type"` | ||
| 14 | } | 18 | } |
| 15 | 19 | ||
| 16 | func (getFileQuery *GetFileQuery) Valid(validation *validation.Validation) { | 20 | func (getFileQuery *GetFileQuery) Valid(validation *validation.Validation) { |
| 17 | - validation.SetError("CustomValid", "未实现的自定义认证") | 21 | + |
| 18 | } | 22 | } |
| 19 | 23 | ||
| 20 | func (getFileQuery *GetFileQuery) ValidateQuery() error { | 24 | func (getFileQuery *GetFileQuery) ValidateQuery() error { |
| @@ -79,7 +79,7 @@ func (fileService *FileService) CreateFile(ctx *domain.Context, createFileComman | @@ -79,7 +79,7 @@ func (fileService *FileService) CreateFile(ctx *domain.Context, createFileComman | ||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | // 返回文件服务 | 81 | // 返回文件服务 |
| 82 | -func (fileService *FileService) GetFile(getFileQuery *query.GetFileQuery) (interface{}, error) { | 82 | +func (fileService *FileService) GetFile(ctx *domain.Context, getFileQuery *query.GetFileQuery) (interface{}, error) { |
| 83 | if err := getFileQuery.ValidateQuery(); err != nil { | 83 | if err := getFileQuery.ValidateQuery(); err != nil { |
| 84 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 84 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| 85 | } | 85 | } |
| @@ -101,18 +101,31 @@ func (fileService *FileService) GetFile(getFileQuery *query.GetFileQuery) (inter | @@ -101,18 +101,31 @@ func (fileService *FileService) GetFile(getFileQuery *query.GetFileQuery) (inter | ||
| 101 | } else { | 101 | } else { |
| 102 | fileRepository = value | 102 | fileRepository = value |
| 103 | } | 103 | } |
| 104 | - file, err := fileRepository.FindOne(map[string]interface{}{"fileId": getFileQuery.FileId}) | ||
| 105 | - if err != nil { | ||
| 106 | - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 104 | + response := map[string]interface{}{ |
| 105 | + "file": nil, | ||
| 107 | } | 106 | } |
| 108 | - if file == nil { | ||
| 109 | - return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%d", getFileQuery.FileId)) | ||
| 110 | - } else { | ||
| 111 | - if err := transactionContext.CommitTransaction(); err != nil { | ||
| 112 | - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 113 | - } | ||
| 114 | - return file, nil | 107 | + options := map[string]interface{}{"context": ctx} |
| 108 | + if getFileQuery.FileId > 0 { | ||
| 109 | + options["fileId"] = getFileQuery.FileId | ||
| 110 | + } | ||
| 111 | + if len(getFileQuery.FileName) > 0 { | ||
| 112 | + options["fileName"] = getFileQuery.FileName | ||
| 113 | + } | ||
| 114 | + if len(getFileQuery.FileType) > 0 { | ||
| 115 | + options["fileType"] = getFileQuery.FileType | ||
| 116 | + } | ||
| 117 | + if len(options) == 0 { | ||
| 118 | + return response, nil | ||
| 119 | + } | ||
| 120 | + file, _ := fileRepository.FindOne(options) | ||
| 121 | + //if err != nil { | ||
| 122 | + // return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 123 | + //} | ||
| 124 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
| 125 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
| 115 | } | 126 | } |
| 127 | + response["file"] = (&dto.FileDto{}).Load(file) | ||
| 128 | + return response, nil | ||
| 116 | } | 129 | } |
| 117 | 130 | ||
| 118 | // 返回文件服务列表 | 131 | // 返回文件服务列表 |
| @@ -13,6 +13,7 @@ import ( | @@ -13,6 +13,7 @@ import ( | ||
| 13 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel" | 13 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel" |
| 14 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" | 14 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" |
| 15 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" | 15 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" |
| 16 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" | ||
| 16 | "strings" | 17 | "strings" |
| 17 | "time" | 18 | "time" |
| 18 | ) | 19 | ) |
| @@ -441,7 +442,7 @@ func (querySetService *QuerySetService) CalculateItemPreview(ctx *domain.Context | @@ -441,7 +442,7 @@ func (querySetService *QuerySetService) CalculateItemPreview(ctx *domain.Context | ||
| 441 | if q.Formula.MixTableModel() { | 442 | if q.Formula.MixTableModel() { |
| 442 | q.Formula.ExprSql = q.Formula.Complete() | 443 | q.Formula.ExprSql = q.Formula.Complete() |
| 443 | } | 444 | } |
| 444 | - _, result := GetItemValues(transactionContext, q) | 445 | + _, result := GetItemValues(ctx, transactionContext, q) |
| 445 | if err := transactionContext.CommitTransaction(); err != nil { | 446 | if err := transactionContext.CommitTransaction(); err != nil { |
| 446 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 447 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 447 | } | 448 | } |
| @@ -464,7 +465,7 @@ func (querySetService *QuerySetService) CalculateItemExport(ctx *domain.Context, | @@ -464,7 +465,7 @@ func (querySetService *QuerySetService) CalculateItemExport(ctx *domain.Context, | ||
| 464 | defer func() { | 465 | defer func() { |
| 465 | transactionContext.RollbackTransaction() | 466 | transactionContext.RollbackTransaction() |
| 466 | }() | 467 | }() |
| 467 | - querySet, result := GetItemValues(transactionContext, q) | 468 | + querySet, result := GetItemValues(ctx, transactionContext, q) |
| 468 | if querySet == nil { | 469 | if querySet == nil { |
| 469 | return nil, err | 470 | return nil, err |
| 470 | } | 471 | } |
| @@ -490,7 +491,7 @@ func (querySetService *QuerySetService) CalculateItemExport(ctx *domain.Context, | @@ -490,7 +491,7 @@ func (querySetService *QuerySetService) CalculateItemExport(ctx *domain.Context, | ||
| 490 | }, err | 491 | }, err |
| 491 | } | 492 | } |
| 492 | 493 | ||
| 493 | -func GetItemValues(transactionContext application.TransactionContext, q *query.CalculateItemPreviewQuery) (*domain.QuerySet, []itemValue) { | 494 | +func GetItemValues(ctx *domain.Context, transactionContext application.TransactionContext, q *query.CalculateItemPreviewQuery) (*domain.QuerySet, []itemValue) { |
| 494 | _, querySet, err := factory.FastPgQuerySet(transactionContext, q.QuerySetId) | 495 | _, querySet, err := factory.FastPgQuerySet(transactionContext, q.QuerySetId) |
| 495 | if err != nil { | 496 | if err != nil { |
| 496 | return nil, nil | 497 | return nil, nil |
| @@ -499,8 +500,24 @@ func GetItemValues(transactionContext application.TransactionContext, q *query.C | @@ -499,8 +500,24 @@ func GetItemValues(transactionContext application.TransactionContext, q *query.C | ||
| 499 | if q.Formula.MixTableModel() { | 500 | if q.Formula.MixTableModel() { |
| 500 | q.Formula.ExprSql = q.Formula.Complete() | 501 | q.Formula.ExprSql = q.Formula.Complete() |
| 501 | } | 502 | } |
| 502 | - value := starrocks.CalculateItemValue(starrocks.DB, q.Formula) | ||
| 503 | - | 503 | + var value string |
| 504 | + if q.Formula.ExprMode == domain.ExprModeExcelFunction { | ||
| 505 | + svr, _ := factory.FastQuerySetServices(transactionContext) | ||
| 506 | + dataTable, err := svr.LoadCalculateItemData(ctx, nil, &domain.FieldFormulaExpr{ | ||
| 507 | + FieldExpr: *q.Formula, | ||
| 508 | + ExprMode: q.Formula.ExprMode, | ||
| 509 | + }) | ||
| 510 | + if err != nil { | ||
| 511 | + log.Logger.Error(err.Error()) | ||
| 512 | + } | ||
| 513 | + if dataTable != nil && len(dataTable.Data) > 0 { | ||
| 514 | + if len(dataTable.Data[0]) > 0 { | ||
| 515 | + value = dataTable.Data[0][0] | ||
| 516 | + } | ||
| 517 | + } | ||
| 518 | + } else { | ||
| 519 | + value = starrocks.CalculateItemValue(starrocks.DB, q.Formula) | ||
| 520 | + } | ||
| 504 | var result = make([]itemValue, 0) | 521 | var result = make([]itemValue, 0) |
| 505 | result = append(result, itemValue{ | 522 | result = append(result, itemValue{ |
| 506 | Name: querySet.Name, | 523 | Name: querySet.Name, |
| @@ -11,13 +11,14 @@ import ( | @@ -11,13 +11,14 @@ import ( | ||
| 11 | ) | 11 | ) |
| 12 | 12 | ||
| 13 | type FieldOptionalValuesCommand struct { | 13 | type FieldOptionalValuesCommand struct { |
| 14 | - ObjectType string `cname:"对象类型" json:"objectType" valid:"Required"` | ||
| 15 | - ObjectId int `cname:"对象Id标识" json:"objectId" valid:"Required"` | ||
| 16 | - Field domain.Field `cname:"列" json:"field" valid:"Required"` | ||
| 17 | - Match string `cname:"匹配内容" json:"match"` | ||
| 18 | - PageNumber int `json:"pageNumber"` | ||
| 19 | - PageSize int `json:"pageSize"` | ||
| 20 | - Condition *domain.Condition `json:"condition"` | 14 | + ObjectType string `cname:"对象类型" json:"objectType" valid:"Required"` |
| 15 | + ObjectId int `cname:"对象Id标识" json:"objectId" valid:"Required"` | ||
| 16 | + Field domain.Field `cname:"列" json:"field" valid:"Required"` | ||
| 17 | + Match string `cname:"匹配内容" json:"match"` | ||
| 18 | + PageNumber int `json:"pageNumber"` | ||
| 19 | + PageSize int `json:"pageSize"` | ||
| 20 | + //Condition []*domain.Condition `json:"conditions"` | ||
| 21 | + Where *domain.Where `json:"where"` | ||
| 21 | } | 22 | } |
| 22 | 23 | ||
| 23 | func (cmd *FieldOptionalValuesCommand) Valid(validation *validation.Validation) { | 24 | func (cmd *FieldOptionalValuesCommand) Valid(validation *validation.Validation) { |
| @@ -90,10 +90,12 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd * | @@ -90,10 +90,12 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd * | ||
| 90 | }, | 90 | }, |
| 91 | }, | 91 | }, |
| 92 | } | 92 | } |
| 93 | - if cmd.Condition != nil { | ||
| 94 | - options.Where = append(options.Where, starrocks.Condition{ | ||
| 95 | - Condition: *cmd.Condition, | ||
| 96 | - }) | 93 | + if cmd.Where != nil && len(cmd.Where.Conditions) > 0 { |
| 94 | + for _, c := range cmd.Where.Conditions { | ||
| 95 | + options.Where = append(options.Where, starrocks.Condition{ | ||
| 96 | + Condition: c, | ||
| 97 | + }) | ||
| 98 | + } | ||
| 97 | } | 99 | } |
| 98 | options.AdditionOptionsByTable(table) | 100 | options.AdditionOptionsByTable(table) |
| 99 | options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize) | 101 | options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize) |
| @@ -10,6 +10,7 @@ import ( | @@ -10,6 +10,7 @@ import ( | ||
| 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/dto" | 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/dto" |
| 11 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/query" | 11 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/query" |
| 12 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 12 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
| 13 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain/astexpr" | ||
| 13 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" | 14 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" |
| 14 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" | 15 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" |
| 15 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" | 16 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" |
| @@ -427,32 +428,40 @@ func (tableService *TableService) ValidExprSql(ctx *domain.Context, cmd *command | @@ -427,32 +428,40 @@ func (tableService *TableService) ValidExprSql(ctx *domain.Context, cmd *command | ||
| 427 | if err := cmd.ValidateCommand(); err != nil { | 428 | if err := cmd.ValidateCommand(); err != nil { |
| 428 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 429 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
| 429 | } | 430 | } |
| 430 | - | ||
| 431 | - set := collection.NewSet() | ||
| 432 | - for _, f := range cmd.TableFields { | ||
| 433 | - set.AddStr(f.TableSqlName) | ||
| 434 | - } | ||
| 435 | - if cmd.MixTableModel() { | ||
| 436 | - cmd.ExprSql = cmd.Complete() | ||
| 437 | - } | ||
| 438 | - selectValue := cmd.ExprSql | ||
| 439 | - //if _, parseErr := strconv.ParseFloat(cmd.ExprSql, 64); parseErr != nil { | ||
| 440 | - // selectValue = "'" + selectValue + "'" | ||
| 441 | - //} | ||
| 442 | - if len(cmd.ExprSql) == 0 { | ||
| 443 | - selectValue = "''" | ||
| 444 | - } | ||
| 445 | - sql := "select " + selectValue + " as expr" | ||
| 446 | - if len(set.KeysStr()) > 0 { | ||
| 447 | - sql += " from " + strings.Join(set.KeysStr(), ",") | ||
| 448 | - sql += " limit 1" | ||
| 449 | - } | ||
| 450 | - tx := starrocks.DB.Exec(sql) | ||
| 451 | - if tx.Error != nil { | ||
| 452 | - return map[string]string{ | ||
| 453 | - "result": tx.Error.Error(), | ||
| 454 | - }, nil | 431 | + switch cmd.FieldExpr.ExprMode { |
| 432 | + case domain.ExprModeSql: | ||
| 433 | + set := collection.NewSet() | ||
| 434 | + for _, f := range cmd.TableFields { | ||
| 435 | + set.AddStr(f.TableSqlName) | ||
| 436 | + } | ||
| 437 | + if cmd.MixTableModel() { | ||
| 438 | + cmd.ExprSql = cmd.Complete() | ||
| 439 | + } | ||
| 440 | + selectValue := cmd.ExprSql | ||
| 441 | + if len(cmd.ExprSql) == 0 { | ||
| 442 | + selectValue = "''" | ||
| 443 | + } | ||
| 444 | + sql := "select " + selectValue + " as expr" | ||
| 445 | + if len(set.KeysStr()) > 0 { | ||
| 446 | + sql += " from " + strings.Join(set.KeysStr(), ",") | ||
| 447 | + sql += " limit 1" | ||
| 448 | + } | ||
| 449 | + tx := starrocks.DB.Exec(sql) | ||
| 450 | + if tx.Error != nil { | ||
| 451 | + return map[string]string{ | ||
| 452 | + "result": tx.Error.Error(), | ||
| 453 | + }, nil | ||
| 454 | + } | ||
| 455 | + case domain.ExprModeExcelFunction: | ||
| 456 | + _, err := astexpr.NewExprAST(cmd.ExprSql) | ||
| 457 | + if err != nil { | ||
| 458 | + return map[string]string{ | ||
| 459 | + "result": err.Error(), | ||
| 460 | + }, nil | ||
| 461 | + } | ||
| 462 | + default: | ||
| 455 | } | 463 | } |
| 464 | + | ||
| 456 | return struct{}{}, nil | 465 | return struct{}{}, nil |
| 457 | } | 466 | } |
| 458 | 467 |
| @@ -4,6 +4,7 @@ import ( | @@ -4,6 +4,7 @@ import ( | ||
| 4 | "fmt" | 4 | "fmt" |
| 5 | "github.com/go-gota/gota/dataframe" | 5 | "github.com/go-gota/gota/dataframe" |
| 6 | "github.com/go-gota/gota/series" | 6 | "github.com/go-gota/gota/series" |
| 7 | + "github.com/shopspring/decimal" | ||
| 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
| 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" | 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" |
| 9 | "strings" | 10 | "strings" |
| @@ -16,6 +17,17 @@ type Calculator struct { | @@ -16,6 +17,17 @@ type Calculator struct { | ||
| 16 | } | 17 | } |
| 17 | 18 | ||
| 18 | func NewCalculator(expr string) (*Calculator, error) { | 19 | func NewCalculator(expr string) (*Calculator, error) { |
| 20 | + ar, err := NewExprAST(expr) | ||
| 21 | + if err != nil { | ||
| 22 | + return nil, err | ||
| 23 | + } | ||
| 24 | + cal := &Calculator{ | ||
| 25 | + ExprAST: ar, | ||
| 26 | + } | ||
| 27 | + return cal, nil | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +func NewExprAST(expr string) (ExprAST, error) { | ||
| 19 | toks, err := ParseToken(expr) | 31 | toks, err := ParseToken(expr) |
| 20 | if err != nil { | 32 | if err != nil { |
| 21 | return nil, err | 33 | return nil, err |
| @@ -28,11 +40,7 @@ func NewCalculator(expr string) (*Calculator, error) { | @@ -28,11 +40,7 @@ func NewCalculator(expr string) (*Calculator, error) { | ||
| 28 | if ast.Err != nil { | 40 | if ast.Err != nil { |
| 29 | return nil, ast.Err | 41 | return nil, ast.Err |
| 30 | } | 42 | } |
| 31 | - | ||
| 32 | - cal := &Calculator{ | ||
| 33 | - ExprAST: ar, | ||
| 34 | - } | ||
| 35 | - return cal, nil | 43 | + return ar, nil |
| 36 | } | 44 | } |
| 37 | 45 | ||
| 38 | func (cal *Calculator) SetDataTable(t *domain.DataTable) *Calculator { | 46 | func (cal *Calculator) SetDataTable(t *domain.DataTable) *Calculator { |
| @@ -106,19 +114,21 @@ func (cal *Calculator) callDef(name string, args []*param) *param { | @@ -106,19 +114,21 @@ func (cal *Calculator) callDef(name string, args []*param) *param { | ||
| 106 | 114 | ||
| 107 | func (cal *Calculator) sum(params ...*param) *param { | 115 | func (cal *Calculator) sum(params ...*param) *param { |
| 108 | var res = make([]string, 0) | 116 | var res = make([]string, 0) |
| 109 | - var total float64 | 117 | + var total = decimal.NewFromFloat(0) |
| 110 | for _, p := range params { | 118 | for _, p := range params { |
| 111 | for _, v := range p.data { | 119 | for _, v := range p.data { |
| 112 | - total += utils.NewNumberString(v).MustFloat64() | 120 | + dv, _ := decimal.NewFromString(v) |
| 121 | + total = total.Add(dv) | ||
| 113 | } | 122 | } |
| 114 | } | 123 | } |
| 115 | - res = append(res, utils.AssertString(total)) | 124 | + res = append(res, total.String()) |
| 116 | return NewResult(res) | 125 | return NewResult(res) |
| 117 | } | 126 | } |
| 118 | 127 | ||
| 119 | func (cal *Calculator) sumifs(params ...*param) *param { | 128 | func (cal *Calculator) sumifs(params ...*param) *param { |
| 120 | var list = make([]series.Series, 0) | 129 | var list = make([]series.Series, 0) |
| 121 | var filters = make([]dataframe.F, 0) | 130 | var filters = make([]dataframe.F, 0) |
| 131 | + var groupBy = make([]string, 0) | ||
| 122 | for i := 0; i < len(params)-1; i++ { | 132 | for i := 0; i < len(params)-1; i++ { |
| 123 | col := colName(i) | 133 | col := colName(i) |
| 124 | if i == 0 { | 134 | if i == 0 { |
| @@ -126,15 +136,27 @@ func (cal *Calculator) sumifs(params ...*param) *param { | @@ -126,15 +136,27 @@ func (cal *Calculator) sumifs(params ...*param) *param { | ||
| 126 | continue | 136 | continue |
| 127 | } | 137 | } |
| 128 | if i%2 == 1 { | 138 | if i%2 == 1 { |
| 129 | - list = append(list, series.New(params[i+1].Data(), series.String, col)) | ||
| 130 | - if f, ok := cal.resolverFilter(col, params[i]); ok { | ||
| 131 | - filters = append(filters, f) | 139 | + list = append(list, series.New(params[i].Data(), series.String, col)) |
| 140 | + // TODO 类型是行字段判断为按行分组 | ||
| 141 | + if params[i+1].Len() > 1 { | ||
| 142 | + groupBy = append(groupBy, col) | ||
| 143 | + } else { | ||
| 144 | + if f, ok := cal.resolverFilter(col, params[i+1]); ok { | ||
| 145 | + filters = append(filters, f) | ||
| 146 | + } | ||
| 132 | } | 147 | } |
| 133 | i++ | 148 | i++ |
| 134 | } | 149 | } |
| 135 | } | 150 | } |
| 136 | df := dataframe.New(list...) | 151 | df := dataframe.New(list...) |
| 137 | df = df.FilterAggregation(dataframe.And, filters...) | 152 | df = df.FilterAggregation(dataframe.And, filters...) |
| 153 | + if len(groupBy) > 0 { | ||
| 154 | + groups := df.GroupBy(groupBy...) | ||
| 155 | + df = groups.Aggregation([]dataframe.AggregationType{dataframe.Aggregation_SUM}, []string{"A0"}) | ||
| 156 | + s := df.Col("A0_SUM") | ||
| 157 | + return NewResult(toArrayFloat(s.Records())) //4000.00 需要格式化掉后缀 .00 | ||
| 158 | + } | ||
| 159 | + | ||
| 138 | s := df.Col("A0") | 160 | s := df.Col("A0") |
| 139 | return NewResult(s.Records()) | 161 | return NewResult(s.Records()) |
| 140 | } | 162 | } |
| @@ -220,17 +242,21 @@ func (cal *Calculator) OpCalc(op string, lp *param, rp *param) *param { | @@ -220,17 +242,21 @@ func (cal *Calculator) OpCalc(op string, lp *param, rp *param) *param { | ||
| 220 | } | 242 | } |
| 221 | 243 | ||
| 222 | func opCalc(op, v1, v2 string) string { | 244 | func opCalc(op, v1, v2 string) string { |
| 223 | - fv1 := utils.NumberString(v1).MustFloat64() | ||
| 224 | - fv2 := utils.NumberString(v2).MustFloat64() | 245 | + //fv1 := utils.NumberString(v1).MustFloat64() |
| 246 | + //fv2 := utils.NumberString(v2).MustFloat64() | ||
| 247 | + | ||
| 248 | + fv1, _ := decimal.NewFromString(v1) | ||
| 249 | + fv2, _ := decimal.NewFromString(v2) | ||
| 225 | switch op { | 250 | switch op { |
| 226 | case "+": | 251 | case "+": |
| 227 | - return utils.AssertString(fv1 + fv2) | 252 | + |
| 253 | + return utils.AssertString(fv1.Add(fv2).String()) | ||
| 228 | case "-": | 254 | case "-": |
| 229 | - return utils.AssertString(fv1 - fv2) | 255 | + return utils.AssertString(fv1.Sub(fv2).String()) // utils.Round(fv1-fv2, 15) |
| 230 | case "*": | 256 | case "*": |
| 231 | - return utils.AssertString(fv1 * fv2) | 257 | + return utils.AssertString(fv1.Mul(fv2).String()) |
| 232 | case "/": | 258 | case "/": |
| 233 | - return utils.AssertString(fv1 / fv2) | 259 | + return utils.AssertString(fv1.Div(fv2).String()) |
| 234 | } | 260 | } |
| 235 | return "" | 261 | return "" |
| 236 | } | 262 | } |
| @@ -252,3 +278,10 @@ func NewResult(data []string) *param { | @@ -252,3 +278,10 @@ func NewResult(data []string) *param { | ||
| 252 | data: data, | 278 | data: data, |
| 253 | } | 279 | } |
| 254 | } | 280 | } |
| 281 | + | ||
| 282 | +func toArrayFloat(list []string) []string { | ||
| 283 | + for i := range list { | ||
| 284 | + list[i] = utils.AssertString(utils.NewNumberString(list[i]).MustFloat64()) | ||
| 285 | + } | ||
| 286 | + return list | ||
| 287 | +} |
| @@ -125,19 +125,27 @@ func TestSumIfCalculator(t *testing.T) { | @@ -125,19 +125,27 @@ func TestSumIfCalculator(t *testing.T) { | ||
| 125 | want []string | 125 | want []string |
| 126 | }{ | 126 | }{ |
| 127 | { | 127 | { |
| 128 | - expr: `sum(sumifs(销售明细.业绩,"3月",销售明细.月份))`, | 128 | + expr: `sum(sumifs(销售明细.业绩,销售明细.月份,"3月"))`, |
| 129 | want: []string{"40000"}, | 129 | want: []string{"40000"}, |
| 130 | }, | 130 | }, |
| 131 | { | 131 | { |
| 132 | - expr: `sum(sumifs(销售明细.业绩,"3月",销售明细.月份,"<25000",销售明细.业绩))`, | 132 | + expr: `sum(sumifs(销售明细.业绩,销售明细.月份,"3月",销售明细.业绩,"<25000"))`, |
| 133 | want: []string{"40000"}, | 133 | want: []string{"40000"}, |
| 134 | }, | 134 | }, |
| 135 | { | 135 | { |
| 136 | - expr: `sum(sumifs(销售明细.业绩,"3*",销售明细.月份))`, | 136 | + expr: `sum(sumifs(销售明细.业绩,销售明细.月份,"3*"))`, |
| 137 | want: []string{"40000"}, | 137 | want: []string{"40000"}, |
| 138 | }, | 138 | }, |
| 139 | { | 139 | { |
| 140 | - expr: `sum(sumifs(销售明细.业绩,"*月",销售明细.月份))`, | 140 | + expr: `sum(sumifs(销售明细.业绩,销售明细.月份,"*月"))`, |
| 141 | + want: []string{"50000"}, | ||
| 142 | + }, | ||
| 143 | + { | ||
| 144 | + expr: `sumifs(销售明细.业绩,销售明细.月份,销售明细.月份)`, | ||
| 145 | + want: []string{"10000", "40000"}, | ||
| 146 | + }, | ||
| 147 | + { | ||
| 148 | + expr: `sum(sumifs(销售明细.业绩,销售明细.月份,销售明细.月份))`, | ||
| 141 | want: []string{"50000"}, | 149 | want: []string{"50000"}, |
| 142 | }, | 150 | }, |
| 143 | } | 151 | } |
| @@ -202,7 +202,7 @@ func (p *Parser) isDigitNum(c rune) bool { | @@ -202,7 +202,7 @@ func (p *Parser) isDigitNum(c rune) bool { | ||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | func (p *Parser) isChar(c rune) bool { | 204 | func (p *Parser) isChar(c rune) bool { |
| 205 | - return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '.' || c == '"' || isChineseCharacter(c) | 205 | + return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '.' || c == '"' || isChineseCharacter(c) || c == '_' //|| p.isDigitNum(c) |
| 206 | //判断是汉字 | 206 | //判断是汉字 |
| 207 | } | 207 | } |
| 208 | 208 |
| @@ -89,6 +89,10 @@ func (t *DataTable) Values(f *Field) []string { | @@ -89,6 +89,10 @@ func (t *DataTable) Values(f *Field) []string { | ||
| 89 | index = i | 89 | index = i |
| 90 | break | 90 | break |
| 91 | } | 91 | } |
| 92 | + if t.Fields[i].Name == f.SQLName { | ||
| 93 | + index = i | ||
| 94 | + break | ||
| 95 | + } | ||
| 92 | } | 96 | } |
| 93 | if index < 0 { | 97 | if index < 0 { |
| 94 | return res | 98 | return res |
| @@ -5,6 +5,11 @@ import ( | @@ -5,6 +5,11 @@ import ( | ||
| 5 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" | 5 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" |
| 6 | ) | 6 | ) |
| 7 | 7 | ||
| 8 | +const ( | ||
| 9 | + ExprModeSql = iota | ||
| 10 | + ExprModeExcelFunction | ||
| 11 | +) | ||
| 12 | + | ||
| 8 | var ( | 13 | var ( |
| 9 | ErrorNotFound = fmt.Errorf("没有此资源") | 14 | ErrorNotFound = fmt.Errorf("没有此资源") |
| 10 | ) | 15 | ) |
| @@ -38,6 +38,16 @@ func (f *Field) SqlTypeEqual(compare *Field) bool { | @@ -38,6 +38,16 @@ func (f *Field) SqlTypeEqual(compare *Field) bool { | ||
| 38 | return false | 38 | return false |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | +func (f *Field) SqlTypeToDB() string { | ||
| 42 | + if f.SQLType == Float.ToString() { | ||
| 43 | + return DECIMALV2.ToString() | ||
| 44 | + } | ||
| 45 | + if f.SQLType == Date.ToString() || f.SQLType == Datetime.ToString() { | ||
| 46 | + return "timestamp" | ||
| 47 | + } | ||
| 48 | + return f.SQLType | ||
| 49 | +} | ||
| 50 | + | ||
| 41 | func (f *Field) Valid() error { | 51 | func (f *Field) Valid() error { |
| 42 | if _, ok := SQLTypeMap[strings.ToUpper(f.SQLType)]; !ok { | 52 | if _, ok := SQLTypeMap[strings.ToUpper(f.SQLType)]; !ok { |
| 43 | return fmt.Errorf("unknown sql type:%v", f.SQLType) | 53 | return fmt.Errorf("unknown sql type:%v", f.SQLType) |
| @@ -100,7 +110,7 @@ func (fields Fields) Select(options map[string]interface{}) []*Field { | @@ -100,7 +110,7 @@ func (fields Fields) Select(options map[string]interface{}) []*Field { | ||
| 100 | func ValidFields(fields []*Field) error { | 110 | func ValidFields(fields []*Field) error { |
| 101 | m := (Fields)(fields).ToMap() | 111 | m := (Fields)(fields).ToMap() |
| 102 | if len(m) != len(fields) { | 112 | if len(m) != len(fields) { |
| 103 | - return fmt.Errorf("列名重复发") | 113 | + return fmt.Errorf("列名重复") |
| 104 | } | 114 | } |
| 105 | 115 | ||
| 106 | for _, f := range fields { | 116 | for _, f := range fields { |
| @@ -127,6 +127,11 @@ func (querySet *QuerySet) GetDependencyTables(queryComponents []*QueryComponent) | @@ -127,6 +127,11 @@ func (querySet *QuerySet) GetDependencyTables(queryComponents []*QueryComponent) | ||
| 127 | set.AddInt(f.TableId) | 127 | set.AddInt(f.TableId) |
| 128 | } | 128 | } |
| 129 | } | 129 | } |
| 130 | + if queryComponents[i].Layout != nil { | ||
| 131 | + for _, c := range queryComponents[i].Layout.LayoutCells() { | ||
| 132 | + set.AddInt(c.Data.TableField.TableId) | ||
| 133 | + } | ||
| 134 | + } | ||
| 130 | } | 135 | } |
| 131 | res := set.KeysInt() | 136 | res := set.KeysInt() |
| 132 | sort.Ints(res) | 137 | sort.Ints(res) |
| @@ -68,6 +68,7 @@ func (c ConditionExpr) ExprHuman() string { | @@ -68,6 +68,7 @@ func (c ConditionExpr) ExprHuman() string { | ||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | type FieldFormulaExpr struct { | 70 | type FieldFormulaExpr struct { |
| 71 | + ExprMode int `json:"exprMode"` // 表达式模式 0:sql 1:excel function | ||
| 71 | FieldExpr | 72 | FieldExpr |
| 72 | } | 73 | } |
| 73 | 74 | ||
| @@ -93,6 +94,7 @@ type SelectExprGroup struct { // 查询表达式 | @@ -93,6 +94,7 @@ type SelectExprGroup struct { // 查询表达式 | ||
| 93 | } | 94 | } |
| 94 | 95 | ||
| 95 | type FieldExpr struct { | 96 | type FieldExpr struct { |
| 97 | + ExprMode int `json:"exprMode,omitempty"` | ||
| 96 | TableFields []TableField `json:"tableFields"` | 98 | TableFields []TableField `json:"tableFields"` |
| 97 | ExprHuman string `json:"exprHuman"` | 99 | ExprHuman string `json:"exprHuman"` |
| 98 | ExprSql string `json:"exprSql"` | 100 | ExprSql string `json:"exprSql"` |
| @@ -188,7 +188,7 @@ func NewTableAppendRequest(param domain.ReqAppendData) TableAppendRequest { | @@ -188,7 +188,7 @@ func NewTableAppendRequest(param domain.ReqAppendData) TableAppendRequest { | ||
| 188 | OriginalTableId: intToString(param.FileId), | 188 | OriginalTableId: intToString(param.FileId), |
| 189 | CheckoutTableFileUrl: param.FileUrl, | 189 | CheckoutTableFileUrl: param.FileUrl, |
| 190 | DatabaseTableName: param.Table.SQLName, | 190 | DatabaseTableName: param.Table.SQLName, |
| 191 | - ColumnSchemas: DomainFieldsToColumnSchemas(param.From), //param.ExcelTable.DataFields | 191 | + ColumnSchemas: DomainFieldsToColumnSchemas(param.ExcelTable.DataFields), //这里主要需要传递原文件所有字段 param.From |
| 192 | FieldSchemas: ToFieldSchemas(param.Table.DataFields), | 192 | FieldSchemas: ToFieldSchemas(param.Table.DataFields), |
| 193 | SchemaMap: make(map[string]domain.ColumnSchema), | 193 | SchemaMap: make(map[string]domain.ColumnSchema), |
| 194 | } | 194 | } |
| @@ -2,12 +2,12 @@ package domainService | @@ -2,12 +2,12 @@ package domainService | ||
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "bytes" | 4 | "bytes" |
| 5 | - | ||
| 6 | "github.com/beego/beego/v2/client/httplib" | 5 | "github.com/beego/beego/v2/client/httplib" |
| 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" | 6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant" |
| 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
| 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api/bytelib" | 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/api/bytelib" |
| 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel" | 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/excel" |
| 10 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" | ||
| 11 | ) | 11 | ) |
| 12 | 12 | ||
| 13 | type ByteCoreService struct { | 13 | type ByteCoreService struct { |
| @@ -147,6 +147,12 @@ func (ptr *ByteCoreService) FormulasGenerate(param domain.ReqFormulasGenerate) ( | @@ -147,6 +147,12 @@ func (ptr *ByteCoreService) FormulasGenerate(param domain.ReqFormulasGenerate) ( | ||
| 147 | // } | 147 | // } |
| 148 | // return &domain.DataFormulasGenerate{}, nil | 148 | // return &domain.DataFormulasGenerate{}, nil |
| 149 | //} | 149 | //} |
| 150 | + //if param.QuerySet.Type == domain.CalculateItem.ToString() { | ||
| 151 | + // if param.QuerySet.QueryComponents[0].Formula.ExprMode != 0 { | ||
| 152 | + // err := ptr.ExcelExprCalcPersistence(param.QuerySet.QueryComponents[0].Formula, param, true) | ||
| 153 | + // return &domain.DataFormulasGenerate{}, err | ||
| 154 | + // } | ||
| 155 | + //} | ||
| 150 | if param.QuerySet.Type == domain.CalculateSet.ToString() { | 156 | if param.QuerySet.Type == domain.CalculateSet.ToString() { |
| 151 | _, err := param.QuerySetService.(*QuerySetService).LoadCalculateSetData(param.Context.(*domain.Context), param.QuerySet, param.QueryComponents) | 157 | _, err := param.QuerySetService.(*QuerySetService).LoadCalculateSetData(param.Context.(*domain.Context), param.QuerySet, param.QueryComponents) |
| 152 | if err != nil { | 158 | if err != nil { |
| @@ -162,6 +168,24 @@ func (ptr *ByteCoreService) FormulasClear(param domain.ReqFormulasClear) (*domai | @@ -162,6 +168,24 @@ func (ptr *ByteCoreService) FormulasClear(param domain.ReqFormulasClear) (*domai | ||
| 162 | return apiByteLib.FormulasClear(param) | 168 | return apiByteLib.FormulasClear(param) |
| 163 | } | 169 | } |
| 164 | 170 | ||
| 171 | +func (ptr *ByteCoreService) ExcelExprCalcPersistence(expr *domain.FieldFormulaExpr, param domain.ReqFormulasGenerate, persistence bool) error { | ||
| 172 | + if len(param.QueryComponents) == 0 { | ||
| 173 | + return nil | ||
| 174 | + } | ||
| 175 | + // 加载Tables数据 | ||
| 176 | + q := param.QueryComponents[0] | ||
| 177 | + result, err := param.QuerySetService.(*QuerySetService).LoadCalculateItemData(param.Context.(*domain.Context), param.Table, q.Formula) | ||
| 178 | + if err != nil { | ||
| 179 | + return err | ||
| 180 | + } | ||
| 181 | + if persistence { | ||
| 182 | + starrocks.DropView(starrocks.DB, param.Table.SQLName) | ||
| 183 | + starrocks.DropTable(starrocks.DB, param.Table.SQLName) | ||
| 184 | + return starrocks.Exec(starrocks.DB, starrocks.CreateTableSql(param.Table.SQLName, param.Table.Fields(false), result.Data[0])) | ||
| 185 | + } | ||
| 186 | + return nil | ||
| 187 | +} | ||
| 188 | + | ||
| 165 | ////////////// | 189 | ////////////// |
| 166 | // 字库核心 | 190 | // 字库核心 |
| 167 | ////////////// | 191 | ////////////// |
| @@ -176,6 +176,8 @@ func (ptr *QuerySetService) UpdateCalculateItem(ctx *domain.Context, qs *domain. | @@ -176,6 +176,8 @@ func (ptr *QuerySetService) UpdateCalculateItem(ctx *domain.Context, qs *domain. | ||
| 176 | QuerySet: qs, | 176 | QuerySet: qs, |
| 177 | Table: table, | 177 | Table: table, |
| 178 | QueryComponents: queryComponents, | 178 | QueryComponents: queryComponents, |
| 179 | + QuerySetService: ptr, | ||
| 180 | + Context: ctx, | ||
| 179 | }) | 181 | }) |
| 180 | if err != nil { | 182 | if err != nil { |
| 181 | return err | 183 | return err |
| @@ -751,18 +753,12 @@ func (ptr *QuerySetService) CreateOrUpdateCalculateItemTable(ctx *domain.Context | @@ -751,18 +753,12 @@ func (ptr *QuerySetService) CreateOrUpdateCalculateItemTable(ctx *domain.Context | ||
| 751 | dependencyTables := querySet.GetDependencyTables(queryComponents) | 753 | dependencyTables := querySet.GetDependencyTables(queryComponents) |
| 752 | tableRepository, _ := repository.NewTableRepository(ptr.transactionContext) | 754 | tableRepository, _ := repository.NewTableRepository(ptr.transactionContext) |
| 753 | queryComponent := queryComponents[0] | 755 | queryComponent := queryComponents[0] |
| 754 | - //!!!warning:每个字段默认需要带函数,没有就补全max() | ||
| 755 | - //if queryComponent.Formula.MixTableModel() { | ||
| 756 | - // queryComponent.Formula.Complete() | ||
| 757 | - //} | ||
| 758 | builder := NewDataFieldsBuilder() | 756 | builder := NewDataFieldsBuilder() |
| 759 | - //field := DataField(querySet.Name, domain.String.ToString(), domain.MainTableField, 1) | ||
| 760 | field := builder.NewDataField(querySet.Name, domain.String.ToString(), domain.MainTableField) | 757 | field := builder.NewDataField(querySet.Name, domain.String.ToString(), domain.MainTableField) |
| 761 | if len(queryComponent.Formula.TableFields) > 0 { | 758 | if len(queryComponent.Formula.TableFields) > 0 { |
| 762 | field.SQLType = queryComponent.Formula.TableFields[0].FieldSQLType | 759 | field.SQLType = queryComponent.Formula.TableFields[0].FieldSQLType |
| 763 | } | 760 | } |
| 764 | var table *domain.Table = NewCopyTable(domain.TableType(querySet.Type), querySet.Name, []*domain.Field{field}, 1).WithContext(ctx).WithPrefix(strings.ToLower(querySet.Type)) | 761 | var table *domain.Table = NewCopyTable(domain.TableType(querySet.Type), querySet.Name, []*domain.Field{field}, 1).WithContext(ctx).WithPrefix(strings.ToLower(querySet.Type)) |
| 765 | - //table.PK = nil | ||
| 766 | if querySet.QuerySetInfo.BindTableId > 0 { | 762 | if querySet.QuerySetInfo.BindTableId > 0 { |
| 767 | table, err = tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableId": querySet.QuerySetInfo.BindTableId}) | 763 | table, err = tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableId": querySet.QuerySetInfo.BindTableId}) |
| 768 | if err != nil { | 764 | if err != nil { |
| 1 | +package domainService | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain/astexpr" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +func (ptr *QuerySetService) LoadCalculateItemData(ctx *domain.Context, t *domain.Table, formula *domain.FieldFormulaExpr) (*domain.DataTable, error) { | ||
| 9 | + var ( | ||
| 10 | + res = &domain.DataTable{} | ||
| 11 | + err error | ||
| 12 | + ) | ||
| 13 | + | ||
| 14 | + calc, err := astexpr.NewCalculator(formula.ExprSql) | ||
| 15 | + if err != nil { | ||
| 16 | + return nil, err | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + if len(formula.TableFields) > 0 { | ||
| 20 | + var tableId = formula.TableFields[0].TableId | ||
| 21 | + mapTable, _ := ptr.loadDataTables(ctx, []int{tableId}) | ||
| 22 | + calc.SetDataTable(mapTable[tableId]) | ||
| 23 | + } | ||
| 24 | + result, err := calc.ExprASTResult(calc.ExprAST) | ||
| 25 | + if err != nil { | ||
| 26 | + return nil, err | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + res.Data = [][]string{ | ||
| 30 | + result.Data(), | ||
| 31 | + } | ||
| 32 | + if t != nil { | ||
| 33 | + res.Fields = t.Fields(false) | ||
| 34 | + } | ||
| 35 | + res.Total = int64(len(res.Data)) | ||
| 36 | + // 数据持久化 | ||
| 37 | + return res, nil | ||
| 38 | +} |
| @@ -225,10 +225,10 @@ func FastDataTable(options starrocks.QueryOptions) (*domain.DataTable, error) { | @@ -225,10 +225,10 @@ func FastDataTable(options starrocks.QueryOptions) (*domain.DataTable, error) { | ||
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | func (ptr *QuerySetService) LoadDataTables(ctx *domain.Context, cells []*domain.LayoutCell) (map[int]*domain.DataTable, error) { | 227 | func (ptr *QuerySetService) LoadDataTables(ctx *domain.Context, cells []*domain.LayoutCell) (map[int]*domain.DataTable, error) { |
| 228 | - var ( | ||
| 229 | - dataTables = make(map[int]*domain.DataTable) | ||
| 230 | - tableRepository, _ = repository.NewTableRepository(ptr.transactionContext) | ||
| 231 | - ) | 228 | + //var ( |
| 229 | + // dataTables = make(map[int]*domain.DataTable) | ||
| 230 | + // tableRepository, _ = repository.NewTableRepository(ptr.transactionContext) | ||
| 231 | + //) | ||
| 232 | tableIds := collection.NewSet() | 232 | tableIds := collection.NewSet() |
| 233 | for _, cell := range cells { | 233 | for _, cell := range cells { |
| 234 | if cell.Data == nil || cell.Data.TableField == nil || cell.Data.TableField.TableId == 0 { | 234 | if cell.Data == nil || cell.Data.TableField == nil || cell.Data.TableField.TableId == 0 { |
| @@ -236,8 +236,34 @@ func (ptr *QuerySetService) LoadDataTables(ctx *domain.Context, cells []*domain. | @@ -236,8 +236,34 @@ func (ptr *QuerySetService) LoadDataTables(ctx *domain.Context, cells []*domain. | ||
| 236 | } | 236 | } |
| 237 | tableIds.AddInt(cell.Data.TableField.TableId) | 237 | tableIds.AddInt(cell.Data.TableField.TableId) |
| 238 | } | 238 | } |
| 239 | - if len(tableIds.KeysInt()) > 0 { | ||
| 240 | - _, tables, err := tableRepository.Find(map[string]interface{}{"context": ctx, "tableIds": tableIds.KeysInt()}) | 239 | + //if len(tableIds.KeysInt()) > 0 { |
| 240 | + // _, tables, err := tableRepository.Find(map[string]interface{}{"context": ctx, "tableIds": tableIds.KeysInt()}) | ||
| 241 | + // if err != nil { | ||
| 242 | + // return nil, err | ||
| 243 | + // } | ||
| 244 | + // for _, t := range tables { | ||
| 245 | + // if _, ok := dataTables[t.TableId]; ok { | ||
| 246 | + // continue | ||
| 247 | + // } | ||
| 248 | + // dataTable, err := FastTable(t) | ||
| 249 | + // if err != nil { | ||
| 250 | + // log.Logger.Error(err.Error()) | ||
| 251 | + // return nil, fmt.Errorf("获取【%s】出现异常:%s", t.Name, err.Error()) | ||
| 252 | + // } | ||
| 253 | + // dataTable.Fields = t.DataFields | ||
| 254 | + // dataTables[t.TableId] = dataTable | ||
| 255 | + // } | ||
| 256 | + //} | ||
| 257 | + return ptr.loadDataTables(ctx, tableIds.KeysInt()) | ||
| 258 | +} | ||
| 259 | + | ||
| 260 | +func (ptr *QuerySetService) loadDataTables(ctx *domain.Context, tableIds []int) (map[int]*domain.DataTable, error) { | ||
| 261 | + var ( | ||
| 262 | + dataTables = make(map[int]*domain.DataTable) | ||
| 263 | + tableRepository, _ = repository.NewTableRepository(ptr.transactionContext) | ||
| 264 | + ) | ||
| 265 | + if len(tableIds) > 0 { | ||
| 266 | + _, tables, err := tableRepository.Find(map[string]interface{}{"context": ctx, "tableIds": tableIds}) | ||
| 241 | if err != nil { | 267 | if err != nil { |
| 242 | return nil, err | 268 | return nil, err |
| 243 | } | 269 | } |
| @@ -112,3 +112,50 @@ create view {{.ViewName}}( | @@ -112,3 +112,50 @@ create view {{.ViewName}}( | ||
| 112 | }) | 112 | }) |
| 113 | return html.UnescapeString(buf.String()) | 113 | return html.UnescapeString(buf.String()) |
| 114 | } | 114 | } |
| 115 | + | ||
| 116 | +func DropTable(db *gorm.DB, tableName string) error { | ||
| 117 | + tx := db.Exec("DROP TABLE IF EXISTS " + tableName) | ||
| 118 | + return tx.Error | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +func CreateTableSql(viewName string, fields []*domain.Field, data []string) string { | ||
| 122 | + sql := ` | ||
| 123 | +## DROP VIEW IF EXISTS {{.ViewName}}; | ||
| 124 | +## DROP TABLE IF EXISTS {{.ViewName}}; | ||
| 125 | +Create TABLE {{.ViewName}} ( | ||
| 126 | +id BIGINT, | ||
| 127 | +{{.Field}} | ||
| 128 | +) | ||
| 129 | +UNIQUE KEY(id) | ||
| 130 | +DISTRIBUTED BY HASH(id) BUCKETS 3 | ||
| 131 | +PROPERTIES("replication_num"="1"); | ||
| 132 | + | ||
| 133 | +TRUNCATE TABLE {{.ViewName}}; | ||
| 134 | + | ||
| 135 | +insert into {{.ViewName}} Values {{.Values}} | ||
| 136 | +` | ||
| 137 | + tmp := template.New("ViewCreator") | ||
| 138 | + tmp.Parse(sql) | ||
| 139 | + | ||
| 140 | + buf := bytes.NewBuffer(nil) | ||
| 141 | + bufField := bytes.NewBuffer(nil) | ||
| 142 | + for i, f := range fields { | ||
| 143 | + bufField.WriteString(fmt.Sprintf(`%s VARCHAR(65533)`, f.SQLName)) //, f.SqlTypeToDB() | ||
| 144 | + if i != len(fields)-1 { | ||
| 145 | + bufField.WriteString(",\n") | ||
| 146 | + } | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + bufInsert := bytes.NewBuffer(nil) | ||
| 150 | + for _, d := range data { | ||
| 151 | + id, _ := utils.NewSnowflakeId() | ||
| 152 | + bufInsert.WriteString(fmt.Sprintf("(%d,'%s')", id, d)) | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + tmp.Execute(buf, map[string]interface{}{ | ||
| 156 | + "ViewName": viewName, | ||
| 157 | + "Field": bufField.String(), | ||
| 158 | + "Values": bufInsert.String(), | ||
| 159 | + }) | ||
| 160 | + return html.UnescapeString(buf.String()) | ||
| 161 | +} |
| @@ -141,7 +141,11 @@ func (c Condition) SetWhere(params QueryOptions, q *gorm.DB) { | @@ -141,7 +141,11 @@ func (c Condition) SetWhere(params QueryOptions, q *gorm.DB) { | ||
| 141 | } | 141 | } |
| 142 | if len(c.In) > 0 { | 142 | if len(c.In) > 0 { |
| 143 | if c.Field.SQLType == domain.Float.ToString() { | 143 | if c.Field.SQLType == domain.Float.ToString() { |
| 144 | - q.Where(fmt.Sprintf("%v in %v", c.CastType(c.Field.SQLName, domain.DECIMALV2.ToString()), c.InArgs(c.In))) | 144 | + if hasEmpty(c.In) { |
| 145 | + q.Where(fmt.Sprintf("((%v in %v) or (%v is null))", c.CastType(c.Field.SQLName, domain.DECIMALV2.ToString()), c.InArgs(c.In), c.Field.SQLName)) | ||
| 146 | + } else { | ||
| 147 | + q.Where(fmt.Sprintf("%v in %v", c.CastType(c.Field.SQLName, domain.DECIMALV2.ToString()), c.InArgs(c.In))) | ||
| 148 | + } | ||
| 145 | } else { | 149 | } else { |
| 146 | q.Where(fmt.Sprintf("%v in %v", c.CastType(c.FormatIfNull(params, c.Field), "string"), c.InArgs(c.In))) | 150 | q.Where(fmt.Sprintf("%v in %v", c.CastType(c.FormatIfNull(params, c.Field), "string"), c.InArgs(c.In))) |
| 147 | } | 151 | } |
| @@ -222,6 +226,15 @@ func formatFiled(f *domain.Field) string { | @@ -222,6 +226,15 @@ func formatFiled(f *domain.Field) string { | ||
| 222 | return f.SQLName | 226 | return f.SQLName |
| 223 | } | 227 | } |
| 224 | 228 | ||
| 229 | +func hasEmpty(in []interface{}) bool { | ||
| 230 | + for _, arg := range in { | ||
| 231 | + if v, ok := arg.(string); ok && len(v) == 0 { | ||
| 232 | + return true | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + return false | ||
| 236 | +} | ||
| 237 | + | ||
| 225 | func castType(sql, t string) string { | 238 | func castType(sql, t string) string { |
| 226 | return fmt.Sprintf("cast(%v as %v)", sql, t) | 239 | return fmt.Sprintf("cast(%v as %v)", sql, t) |
| 227 | } | 240 | } |
| @@ -36,7 +36,9 @@ func (controller *FileController) GetFile() { | @@ -36,7 +36,9 @@ func (controller *FileController) GetFile() { | ||
| 36 | getFileQuery := &query.GetFileQuery{} | 36 | getFileQuery := &query.GetFileQuery{} |
| 37 | fileId, _ := controller.GetInt(":fileId") | 37 | fileId, _ := controller.GetInt(":fileId") |
| 38 | getFileQuery.FileId = fileId | 38 | getFileQuery.FileId = fileId |
| 39 | - data, err := fileService.GetFile(getFileQuery) | 39 | + getFileQuery.FileName = controller.GetString("name") |
| 40 | + getFileQuery.FileType = controller.GetString("type") | ||
| 41 | + data, err := fileService.GetFile(ParseContext(controller.BaseController), getFileQuery) | ||
| 40 | controller.Response(data, err) | 42 | controller.Response(data, err) |
| 41 | } | 43 | } |
| 42 | 44 |
| @@ -9,6 +9,7 @@ func init() { | @@ -9,6 +9,7 @@ func init() { | ||
| 9 | web.Router("/data/files/", &controllers.FileController{}, "Post:CreateFile") | 9 | web.Router("/data/files/", &controllers.FileController{}, "Post:CreateFile") |
| 10 | web.Router("/data/files/:fileId", &controllers.FileController{}, "Put:UpdateFile") | 10 | web.Router("/data/files/:fileId", &controllers.FileController{}, "Put:UpdateFile") |
| 11 | web.Router("/data/files/:fileId", &controllers.FileController{}, "Get:GetFile") | 11 | web.Router("/data/files/:fileId", &controllers.FileController{}, "Get:GetFile") |
| 12 | + web.Router("/data/files", &controllers.FileController{}, "Get:GetFile") | ||
| 12 | web.Router("/data/files/:fileId", &controllers.FileController{}, "Delete:RemoveFile") | 13 | web.Router("/data/files/:fileId", &controllers.FileController{}, "Delete:RemoveFile") |
| 13 | web.Router("/data/files/", &controllers.FileController{}, "Get:ListFile") | 14 | web.Router("/data/files/", &controllers.FileController{}, "Get:ListFile") |
| 14 | web.Router("/data/files/check-status", &controllers.FileController{}, "Post:CheckFileVerifyStatus") | 15 | web.Router("/data/files/check-status", &controllers.FileController{}, "Post:CheckFileVerifyStatus") |
-
请 注册 或 登录 后发表评论