Merge branch 'feat_formula' into test
# Conflicts: # pkg/application/table/dto/table_dto.go
正在显示
31 个修改的文件
包含
1224 行增加
和
53 行删除
1 | +package query | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
6 | + "reflect" | ||
7 | + "strings" | ||
8 | + | ||
9 | + "github.com/beego/beego/v2/core/validation" | ||
10 | +) | ||
11 | + | ||
12 | +type CalculateItemPreviewQuery struct { | ||
13 | + // 查询集合ID | ||
14 | + QuerySetId int `cname:"查询集合ID" json:"querySetId" valid:"Required"` | ||
15 | + // 公式 | ||
16 | + Formula *domain.FieldExpr `json:"formula"` | ||
17 | +} | ||
18 | + | ||
19 | +func (dependencyGraphQuery *CalculateItemPreviewQuery) Valid(validation *validation.Validation) { | ||
20 | + //validation.SetError("CustomValid", "未实现的自定义认证") | ||
21 | +} | ||
22 | + | ||
23 | +func (dependencyGraphQuery *CalculateItemPreviewQuery) ValidateQuery() error { | ||
24 | + valid := validation.Validation{} | ||
25 | + b, err := valid.Valid(dependencyGraphQuery) | ||
26 | + if err != nil { | ||
27 | + return err | ||
28 | + } | ||
29 | + if !b { | ||
30 | + elem := reflect.TypeOf(dependencyGraphQuery).Elem() | ||
31 | + for _, validErr := range valid.Errors { | ||
32 | + field, isExist := elem.FieldByName(validErr.Field) | ||
33 | + if isExist { | ||
34 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
35 | + } else { | ||
36 | + return fmt.Errorf(validErr.Message) | ||
37 | + } | ||
38 | + } | ||
39 | + } | ||
40 | + return nil | ||
41 | +} |
@@ -10,7 +10,8 @@ import ( | @@ -10,7 +10,8 @@ import ( | ||
10 | ) | 10 | ) |
11 | 11 | ||
12 | type SearchQuerySetQuery struct { | 12 | type SearchQuerySetQuery struct { |
13 | - Type string `cname:"类型" json:"type" valid:"Required"` | 13 | + Type string `cname:"类型" json:"type"` |
14 | + Types []string `cname:"类型" json:"types"` | ||
14 | Flag string `cname:"标识" json:"flag"` | 15 | Flag string `cname:"标识" json:"flag"` |
15 | Status int `cname:"状态 1:启用 2:关闭" json:"status"` | 16 | Status int `cname:"状态 1:启用 2:关闭" json:"status"` |
16 | MatchName string `cname:"匹配名称" json:"matchName"` | 17 | MatchName string `cname:"匹配名称" json:"matchName"` |
1 | package service | 1 | package service |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "fmt" | ||
4 | "github.com/linmadan/egglib-go/core/application" | 5 | "github.com/linmadan/egglib-go/core/application" |
5 | "github.com/linmadan/egglib-go/utils/tool_funs" | 6 | "github.com/linmadan/egglib-go/utils/tool_funs" |
6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" |
@@ -9,7 +10,10 @@ import ( | @@ -9,7 +10,10 @@ import ( | ||
9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/querySet/query" | 10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/querySet/query" |
10 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 11 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
11 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" | 12 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService" |
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" | ||
12 | "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 | + "time" | ||
13 | ) | 17 | ) |
14 | 18 | ||
15 | // 查询集合服务 | 19 | // 查询集合服务 |
@@ -373,6 +377,108 @@ func (querySetService *QuerySetService) PreviewPrepare(ctx *domain.Context, upda | @@ -373,6 +377,108 @@ func (querySetService *QuerySetService) PreviewPrepare(ctx *domain.Context, upda | ||
373 | }, nil | 377 | }, nil |
374 | } | 378 | } |
375 | 379 | ||
380 | +func (querySetService *QuerySetService) CalculateItemPreview(ctx *domain.Context, q *query.CalculateItemPreviewQuery) (interface{}, error) { | ||
381 | + if err := q.ValidateQuery(); err != nil { | ||
382 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
383 | + } | ||
384 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
385 | + if err != nil { | ||
386 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
387 | + } | ||
388 | + if err := transactionContext.StartTransaction(); err != nil { | ||
389 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
390 | + } | ||
391 | + defer func() { | ||
392 | + transactionContext.RollbackTransaction() | ||
393 | + }() | ||
394 | + | ||
395 | + _, result := GetItemValues(transactionContext, q) | ||
396 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
397 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
398 | + } | ||
399 | + return map[string]interface{}{ | ||
400 | + "itemValues": result, | ||
401 | + }, nil | ||
402 | +} | ||
403 | + | ||
404 | +func (querySetService *QuerySetService) CalculateItemExport(ctx *domain.Context, q *query.CalculateItemPreviewQuery) (interface{}, error) { | ||
405 | + if err := q.ValidateQuery(); err != nil { | ||
406 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
407 | + } | ||
408 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
409 | + if err != nil { | ||
410 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
411 | + } | ||
412 | + if err := transactionContext.StartTransaction(); err != nil { | ||
413 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
414 | + } | ||
415 | + defer func() { | ||
416 | + transactionContext.RollbackTransaction() | ||
417 | + }() | ||
418 | + querySet, result := GetItemValues(transactionContext, q) | ||
419 | + if querySet == nil { | ||
420 | + return nil, err | ||
421 | + } | ||
422 | + var fields = make([]string, 0) | ||
423 | + var values = make([]string, 0) | ||
424 | + for _, f := range result { | ||
425 | + fields = append(fields, f.Name) | ||
426 | + values = append(values, f.Value) | ||
427 | + } | ||
428 | + | ||
429 | + filename := fmt.Sprintf("%v_%v.xlsx", querySet.Name, time.Now().Format("060102150405")) | ||
430 | + path := fmt.Sprintf("public/%v", filename) | ||
431 | + excelWriter := excel.NewXLXSWriterTo(fields, [][]string{values}) | ||
432 | + if err = excelWriter.Save(path); err != nil { | ||
433 | + return nil, factory.FastError(err) | ||
434 | + } | ||
435 | + | ||
436 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
437 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
438 | + } | ||
439 | + return map[string]interface{}{ | ||
440 | + "url": domain.DownloadUrl(filename), | ||
441 | + }, err | ||
442 | +} | ||
443 | + | ||
444 | +func GetItemValues(transactionContext application.TransactionContext, q *query.CalculateItemPreviewQuery) (*domain.QuerySet, []itemValue) { | ||
445 | + _, querySet, err := factory.FastPgQuerySet(transactionContext, q.QuerySetId) | ||
446 | + if err != nil { | ||
447 | + return nil, nil | ||
448 | + } | ||
449 | + value := starrocks.CalculateItemValue(starrocks.DB, q.Formula) | ||
450 | + | ||
451 | + var result = make([]itemValue, 0) | ||
452 | + result = append(result, itemValue{ | ||
453 | + Name: querySet.Name, | ||
454 | + Value: value, | ||
455 | + }) | ||
456 | + | ||
457 | + for _, f := range q.Formula.TableFields { | ||
458 | + _, table, _ := factory.FastPgTable(transactionContext, f.TableId) | ||
459 | + if table == nil { | ||
460 | + continue | ||
461 | + } | ||
462 | + if table.TableType != domain.CalculateItem.ToString() { | ||
463 | + continue | ||
464 | + } | ||
465 | + value := starrocks.CalculateItemValue(starrocks.DB, &domain.FieldExpr{ | ||
466 | + TableFields: []domain.TableField{f}, | ||
467 | + ExprSql: f.FieldSqlName, | ||
468 | + }) | ||
469 | + result = append(result, itemValue{ | ||
470 | + Name: f.FieldName, | ||
471 | + Value: value, | ||
472 | + }) | ||
473 | + } | ||
474 | + return querySet, result | ||
475 | +} | ||
476 | + | ||
477 | +type itemValue struct { | ||
478 | + Name string `json:"name"` | ||
479 | + Value string `json:"value"` | ||
480 | +} | ||
481 | + | ||
376 | func NewQuerySetService(options map[string]interface{}) *QuerySetService { | 482 | func NewQuerySetService(options map[string]interface{}) *QuerySetService { |
377 | newQuerySetService := &QuerySetService{} | 483 | newQuerySetService := &QuerySetService{} |
378 | return newQuerySetService | 484 | return newQuerySetService |
@@ -21,6 +21,8 @@ type TableDto struct { | @@ -21,6 +21,8 @@ type TableDto struct { | ||
21 | //Module int `json:"module"` | 21 | //Module int `json:"module"` |
22 | // 模块 应用于模块 1:数控中心 2:拆解模块 4:计算模块 | 22 | // 模块 应用于模块 1:数控中心 2:拆解模块 4:计算模块 |
23 | Modules []int `json:"modules"` | 23 | Modules []int `json:"modules"` |
24 | + // 标识 | ||
25 | + Flag string `json:"flag,omitempty"` | ||
24 | // 表字段 | 26 | // 表字段 |
25 | Fields []*domain.Field `json:"fields"` | 27 | Fields []*domain.Field `json:"fields"` |
26 | } | 28 | } |
1 | +package dto | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
5 | +) | ||
6 | + | ||
7 | +type TableObjectDto struct { | ||
8 | + // 序号 | ||
9 | + Id int `json:"id"` | ||
10 | + // 表Id | ||
11 | + TableId int `json:"tableId"` | ||
12 | + // 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表 | ||
13 | + TableType string `json:"tableType"` | ||
14 | + // 名称 | ||
15 | + Name string `json:"name"` | ||
16 | + // 对应数据库名称 | ||
17 | + SQLName string `json:"sqlName,omitempty"` | ||
18 | + // 父级ID | ||
19 | + ParentId int `json:"parentId"` | ||
20 | + // 模块 应用于模块 1:数控中心 2:拆解模块 4:计算模块 | ||
21 | + //Module int `json:"module"` | ||
22 | + // 标识 | ||
23 | + Flag string `json:"flag,omitempty"` | ||
24 | + // 启用状态 | ||
25 | + Status int `json:"status"` | ||
26 | + // 表字段 | ||
27 | + Fields []*domain.Field `json:"fields"` | ||
28 | +} | ||
29 | + | ||
30 | +func (d *TableObjectDto) Load(m *domain.Table) *TableObjectDto { | ||
31 | + d.Id = m.TableId | ||
32 | + d.TableId = m.TableId | ||
33 | + d.TableType = m.TableType | ||
34 | + d.Name = m.Name | ||
35 | + d.ParentId = m.ParentId | ||
36 | + d.SQLName = m.SQLName | ||
37 | + //if m.TableInfo != nil { | ||
38 | + // d.Module = m.TableInfo.ApplyOnModule | ||
39 | + //} | ||
40 | + d.Fields = make([]*domain.Field, 0) | ||
41 | + return d | ||
42 | +} | ||
43 | + | ||
44 | +func (d *TableObjectDto) LoadGroup(m *domain.QuerySet) *TableObjectDto { | ||
45 | + d.Id = m.QuerySetId | ||
46 | + d.TableId = 0 | ||
47 | + d.TableType = m.Type | ||
48 | + d.Name = m.Name | ||
49 | + d.ParentId = m.ParentId | ||
50 | + //if m.TableInfo != nil { | ||
51 | + // d.Module = m.TableInfo.ApplyOnModule | ||
52 | + //} | ||
53 | + d.Status = m.Status | ||
54 | + d.Flag = m.Flag | ||
55 | + d.Fields = make([]*domain.Field, 0) | ||
56 | + return d | ||
57 | +} | ||
58 | + | ||
59 | +func (d *TableObjectDto) Update(m *domain.QuerySet) *TableObjectDto { | ||
60 | + d.Id = m.QuerySetId | ||
61 | + d.Flag = m.Flag | ||
62 | + d.Status = m.Status | ||
63 | + d.ParentId = m.ParentId | ||
64 | + return d | ||
65 | +} | ||
66 | + | ||
67 | +func (d *TableObjectDto) SetDetailStructInfo(m *domain.Table) *TableObjectDto { | ||
68 | + d.Fields = append(d.Fields, m.DataFields...) | ||
69 | + d.Fields = append(d.Fields, m.ManualFields...) | ||
70 | + | ||
71 | + d.SQLName = m.SQLName | ||
72 | + return d | ||
73 | +} |
@@ -12,17 +12,27 @@ import ( | @@ -12,17 +12,27 @@ import ( | ||
12 | type SearchTableQuery struct { | 12 | type SearchTableQuery struct { |
13 | // 表名称 | 13 | // 表名称 |
14 | Name string `cname:"表名称" json:"name"` | 14 | Name string `cname:"表名称" json:"name"` |
15 | - ViewType string `cname:"视图类型 full:完整 main:主表关系" json:"viewType"` | 15 | + //ViewType string `cname:"视图类型 full:完整 main:主表关系" json:"viewType"` |
16 | // 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表 SubProcess:子过程 Schema:方案 | 16 | // 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表 SubProcess:子过程 Schema:方案 |
17 | - TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes"` | 17 | + TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes" valid:"Required"` |
18 | // 父级ID | 18 | // 父级ID |
19 | ParentId int `cname:"父级ID" json:"parentId"` | 19 | ParentId int `cname:"父级ID" json:"parentId"` |
20 | // 模块 应用于模块 1:数控中心 2:拆解模块 4:计算模块 | 20 | // 模块 应用于模块 1:数控中心 2:拆解模块 4:计算模块 |
21 | Module int `json:"module"` | 21 | Module int `json:"module"` |
22 | // 父级ID | 22 | // 父级ID |
23 | ParentTableId int `cname:"父级ID" json:"parentTableId"` | 23 | ParentTableId int `cname:"父级ID" json:"parentTableId"` |
24 | - ReturnDetailStructInfo bool `cname:"返回具体的结构信息 默认不返回" json:"ReturnDetailStructInfo"` | 24 | + // 返回结构信息 |
25 | + ReturnDetailStructInfo bool `cname:"返回具体的结构信息 默认不返回" json:"returnDetailStructInfo"` | ||
26 | + // 排除分组项,只返回一级列表;默认 false 不排除,连分组也返回 | ||
27 | + ReturnGroupItem bool `cname:"排除分组" json:"returnGroupItem"` | ||
25 | Context *domain.Context | 28 | Context *domain.Context |
29 | + FilterRules []*FilterRule `json:"filterRules"` | ||
30 | + TableId int `cname:"ID" json:"tableId"` | ||
31 | +} | ||
32 | +type FilterRule struct { | ||
33 | + // *:匹配所有 | ||
34 | + TableType string `json:"tableType"` | ||
35 | + Status int `json:"status"` | ||
26 | } | 36 | } |
27 | 37 | ||
28 | func (searchQuery *SearchTableQuery) Valid(validation *validation.Validation) { | 38 | func (searchQuery *SearchTableQuery) Valid(validation *validation.Validation) { |
1 | +package query | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
6 | + "reflect" | ||
7 | + "strings" | ||
8 | + | ||
9 | + "github.com/beego/beego/v2/core/validation" | ||
10 | +) | ||
11 | + | ||
12 | +type SearchTableRelationGraphQuery struct { | ||
13 | + // 表名称 | ||
14 | + Name string `cname:"表名称" json:"name"` | ||
15 | + ViewType string `cname:"视图类型 full:完整 main:主表关系" json:"viewType"` | ||
16 | + // 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表 SubProcess:子过程 Schema:方案 | ||
17 | + TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes"` | ||
18 | + // 父级ID | ||
19 | + ParentId int `cname:"父级ID" json:"parentId"` | ||
20 | + // 模块 应用于模块 1:数控中心 2:拆解模块 4:计算模块 | ||
21 | + Module int `json:"module"` | ||
22 | + // 父级ID | ||
23 | + ParentTableId int `cname:"父级ID" json:"parentTableId"` | ||
24 | + ReturnDetailStructInfo bool `cname:"返回具体的结构信息 默认不返回" json:"returnDetailStructInfo"` | ||
25 | + Context *domain.Context | ||
26 | +} | ||
27 | + | ||
28 | +func (searchQuery *SearchTableRelationGraphQuery) Valid(validation *validation.Validation) { | ||
29 | + if searchQuery.ParentTableId > 0 && searchQuery.ParentId == 0 { | ||
30 | + searchQuery.ParentId = searchQuery.ParentTableId | ||
31 | + } | ||
32 | +} | ||
33 | + | ||
34 | +func (searchQuery *SearchTableRelationGraphQuery) ValidateQuery() error { | ||
35 | + valid := validation.Validation{} | ||
36 | + b, err := valid.Valid(searchQuery) | ||
37 | + if err != nil { | ||
38 | + return err | ||
39 | + } | ||
40 | + if !b { | ||
41 | + elem := reflect.TypeOf(searchQuery).Elem() | ||
42 | + for _, validErr := range valid.Errors { | ||
43 | + field, isExist := elem.FieldByName(validErr.Field) | ||
44 | + if isExist { | ||
45 | + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1)) | ||
46 | + } else { | ||
47 | + return fmt.Errorf(validErr.Message) | ||
48 | + } | ||
49 | + } | ||
50 | + } | ||
51 | + return nil | ||
52 | +} |
@@ -249,7 +249,7 @@ func (tableService *TableService) Search(searchQuery *query.SearchTableQuery) (i | @@ -249,7 +249,7 @@ func (tableService *TableService) Search(searchQuery *query.SearchTableQuery) (i | ||
249 | } | 249 | } |
250 | 250 | ||
251 | // 表搜索 | 251 | // 表搜索 |
252 | -func (tableService *TableService) RelationGraph(searchQuery *query.SearchTableQuery) (interface{}, error) { | 252 | +func (tableService *TableService) RelationGraph(searchQuery *query.SearchTableRelationGraphQuery) (interface{}, error) { |
253 | if err := searchQuery.ValidateQuery(); err != nil { | 253 | if err := searchQuery.ValidateQuery(); err != nil { |
254 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | 254 | return nil, application.ThrowError(application.ARG_ERROR, err.Error()) |
255 | } | 255 | } |
@@ -436,6 +436,9 @@ func (tableService *TableService) ValidExprSql(ctx *domain.Context, cmd *command | @@ -436,6 +436,9 @@ func (tableService *TableService) ValidExprSql(ctx *domain.Context, cmd *command | ||
436 | //if _, parseErr := strconv.ParseFloat(cmd.ExprSql, 64); parseErr != nil { | 436 | //if _, parseErr := strconv.ParseFloat(cmd.ExprSql, 64); parseErr != nil { |
437 | // selectValue = "'" + selectValue + "'" | 437 | // selectValue = "'" + selectValue + "'" |
438 | //} | 438 | //} |
439 | + if len(cmd.ExprSql) == 0 { | ||
440 | + selectValue = "''" | ||
441 | + } | ||
439 | sql := "select " + selectValue + " as expr" | 442 | sql := "select " + selectValue + " as expr" |
440 | if len(set.KeysStr()) > 0 { | 443 | if len(set.KeysStr()) > 0 { |
441 | sql += " from " + strings.Join(set.KeysStr(), ",") | 444 | sql += " from " + strings.Join(set.KeysStr(), ",") |
1 | +package service | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "github.com/linmadan/egglib-go/core/application" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/dto" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/query" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" | ||
11 | + "sort" | ||
12 | +) | ||
13 | + | ||
14 | +func (tableService *TableService) TableObjectSearch(searchQuery *query.SearchTableQuery) (interface{}, error) { | ||
15 | + if err := searchQuery.ValidateQuery(); err != nil { | ||
16 | + return nil, application.ThrowError(application.ARG_ERROR, err.Error()) | ||
17 | + } | ||
18 | + transactionContext, err := factory.CreateTransactionContext(nil) | ||
19 | + if err != nil { | ||
20 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
21 | + } | ||
22 | + if err := transactionContext.StartTransaction(); err != nil { | ||
23 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
24 | + } | ||
25 | + defer func() { | ||
26 | + transactionContext.RollbackTransaction() | ||
27 | + }() | ||
28 | + | ||
29 | + tableRepository, _, _ := factory.FastPgTable(transactionContext, 0) | ||
30 | + _, tables, err := tableRepository.Find(utils.ObjectToMap(searchQuery)) | ||
31 | + if err != nil { | ||
32 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
33 | + } | ||
34 | + | ||
35 | + var result = make([]*dto.TableObjectDto, 0) | ||
36 | + for _, table := range tables { | ||
37 | + var item = &dto.TableObjectDto{} | ||
38 | + item.Load(table) | ||
39 | + if searchQuery.ReturnDetailStructInfo { | ||
40 | + item.SetDetailStructInfo(table) | ||
41 | + } | ||
42 | + item.Flag = domain.FlagSet | ||
43 | + if item.TableType == domain.MainTable.ToString() || item.TableType == domain.SubTable.ToString() || item.TableType == domain.SideTable.ToString() { | ||
44 | + item.ParentId = 0 | ||
45 | + item.Status = domain.StatusOn | ||
46 | + } | ||
47 | + result = append(result, item) | ||
48 | + } | ||
49 | + if searchQuery.TableId > 0 { | ||
50 | + return map[string]interface{}{ | ||
51 | + "count": len(result), | ||
52 | + "tableObjects": result, | ||
53 | + }, nil | ||
54 | + } | ||
55 | + | ||
56 | + querySetRepository, _, _ := factory.FastPgQuerySet(transactionContext, 0) | ||
57 | + _, querySets, _ := querySetRepository.Find(map[string]interface{}{"context": searchQuery.Context}) | ||
58 | + if !searchQuery.ReturnGroupItem { | ||
59 | + querySets = make([]*domain.QuerySet, 0) | ||
60 | + } | ||
61 | + // BindTableId , parentId | ||
62 | + querySetMapByTableId := make(map[int]*domain.QuerySet) | ||
63 | + for _, qs := range querySets { | ||
64 | + if qs.QuerySetInfo.BindTableId == 0 { | ||
65 | + continue | ||
66 | + } | ||
67 | + querySetMapByTableId[qs.QuerySetInfo.BindTableId] = qs | ||
68 | + } | ||
69 | + querySetMapById := make(map[int]*domain.QuerySet) | ||
70 | + for _, qs := range querySets { | ||
71 | + querySetMapById[qs.QuerySetId] = qs | ||
72 | + } | ||
73 | + | ||
74 | + var response = make([]*dto.TableObjectDto, 0) | ||
75 | + // 分组 | ||
76 | + querySetMapGroup := make(map[int]bool) | ||
77 | + querySetGroups := make([]*domain.QuerySet, 0) | ||
78 | + for _, t := range result { | ||
79 | + if !domain.TableType(t.TableType).TableHasGroup() { | ||
80 | + response = append(response, t) | ||
81 | + continue | ||
82 | + } | ||
83 | + v, ok := querySetMapByTableId[t.TableId] | ||
84 | + if !ok { | ||
85 | + response = append(response, t) | ||
86 | + continue | ||
87 | + } | ||
88 | + t.Update(v) | ||
89 | + parentGroupId := v.ParentId | ||
90 | + if filterTableByFilterRule(t, searchQuery.FilterRules) { | ||
91 | + continue | ||
92 | + } | ||
93 | + response = append(response, t) | ||
94 | + for { | ||
95 | + if parentGroupId == 0 { | ||
96 | + break | ||
97 | + } | ||
98 | + if _, ok := querySetMapGroup[parentGroupId]; ok { | ||
99 | + break | ||
100 | + } | ||
101 | + querySetMapGroup[parentGroupId] = true | ||
102 | + if v, ok := querySetMapById[parentGroupId]; ok { | ||
103 | + querySetGroups = append(querySetGroups, v) | ||
104 | + parentGroupId = v.ParentId | ||
105 | + } | ||
106 | + } | ||
107 | + } | ||
108 | + | ||
109 | + for _, querySetGroup := range querySetGroups { | ||
110 | + var groupItem = &dto.TableObjectDto{} | ||
111 | + groupItem.LoadGroup(querySetGroup) | ||
112 | + response = append(response, groupItem) | ||
113 | + } | ||
114 | + if err := transactionContext.CommitTransaction(); err != nil { | ||
115 | + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | ||
116 | + } | ||
117 | + | ||
118 | + sort.Slice(response, func(i, j int) bool { | ||
119 | + item1 := response[i] | ||
120 | + item2 := response[j] | ||
121 | + k1 := fmt.Sprintf("%v-%v-%v", item1.TableType, item1.ParentId, item1.Id) | ||
122 | + k2 := fmt.Sprintf("%v-%v-%v", item2.TableType, item2.ParentId, item2.Id) | ||
123 | + return k1 < k2 | ||
124 | + }) | ||
125 | + return map[string]interface{}{ | ||
126 | + "count": len(response), | ||
127 | + "tableObjects": response, | ||
128 | + }, nil | ||
129 | +} | ||
130 | + | ||
131 | +// true:代表需要过滤 false:不需要过滤 | ||
132 | +func filterTableByFilterRule(item *dto.TableObjectDto, filterRules []*query.FilterRule) bool { | ||
133 | + for _, rule := range filterRules { | ||
134 | + if rule.TableType == item.TableType && rule.Status > 0 && rule.Status != item.Status { | ||
135 | + return true | ||
136 | + } | ||
137 | + if rule.TableType == item.TableType && rule.Status == 0 { | ||
138 | + return true | ||
139 | + } | ||
140 | + } | ||
141 | + for _, rule := range filterRules { | ||
142 | + if rule.TableType == "*" && rule.Status > 0 && rule.Status != item.Status { | ||
143 | + return true | ||
144 | + } | ||
145 | + //if rule.TableType == rule.TableType && rule.Status > 0 && rule.Status != item.Status { | ||
146 | + // return true | ||
147 | + //} | ||
148 | + } | ||
149 | + return false | ||
150 | +} |
@@ -34,6 +34,12 @@ var ( | @@ -34,6 +34,12 @@ var ( | ||
34 | RenameQuerySet OperationType = "RenameQuerySet" // 重命名 | 34 | RenameQuerySet OperationType = "RenameQuerySet" // 重命名 |
35 | DeleteQuerySet OperationType = "DeleteQuerySet" // 删除 | 35 | DeleteQuerySet OperationType = "DeleteQuerySet" // 删除 |
36 | 36 | ||
37 | + CreateFormula OperationType = "CreateFormula" // 新增公式 | ||
38 | + DeleteFormula OperationType = "DeleteFormula" // 删除公式 | ||
39 | + EditCalculateItem OperationType = "EditCalculateItem" // 编辑公式 | ||
40 | + EditCalculateTable OperationType = "EditCalculateTable" // 编辑计算表 | ||
41 | + EditCalculateSet OperationType = "EditCalculateSet" // 编辑计算集 | ||
42 | + | ||
37 | UnKnown OperationType = "UnKnown" // 未知 | 43 | UnKnown OperationType = "UnKnown" // 未知 |
38 | ) | 44 | ) |
39 | 45 | ||
@@ -60,12 +66,19 @@ var OperationTypeMap = map[string]string{ | @@ -60,12 +66,19 @@ var OperationTypeMap = map[string]string{ | ||
60 | CopyQuerySet.ToString(): "复制", | 66 | CopyQuerySet.ToString(): "复制", |
61 | RenameQuerySet.ToString(): "重命名", | 67 | RenameQuerySet.ToString(): "重命名", |
62 | DeleteQuerySet.ToString(): "删除", | 68 | DeleteQuerySet.ToString(): "删除", |
69 | + | ||
70 | + CreateFormula.ToString(): "新增公式", | ||
71 | + DeleteFormula.ToString(): "删除公式", | ||
72 | + EditCalculateItem.ToString(): "编辑公式", | ||
73 | + EditCalculateTable.ToString(): "编辑计算表", | ||
74 | + EditCalculateSet.ToString(): "编辑计算集", | ||
63 | } | 75 | } |
64 | 76 | ||
65 | var ( | 77 | var ( |
66 | VerifiedStepLog LogType = "VerifiedStepLog" | 78 | VerifiedStepLog LogType = "VerifiedStepLog" |
67 | CommonLog LogType = "CommonLog" | 79 | CommonLog LogType = "CommonLog" |
68 | QuerySetLog LogType = "QuerySetLog" | 80 | QuerySetLog LogType = "QuerySetLog" |
81 | + FormulaLog LogType = "FormulaLog" | ||
69 | ) | 82 | ) |
70 | 83 | ||
71 | var ( | 84 | var ( |
@@ -97,6 +110,8 @@ var ObjectTypeMap = map[string]string{ | @@ -97,6 +110,8 @@ var ObjectTypeMap = map[string]string{ | ||
97 | ObjectDBTable: "业务表", | 110 | ObjectDBTable: "业务表", |
98 | SchemaTable.ToString(): "方案", | 111 | SchemaTable.ToString(): "方案", |
99 | SubProcessTable.ToString(): "子过程", | 112 | SubProcessTable.ToString(): "子过程", |
113 | + CalculateItem.ToString(): "计算项", | ||
114 | + CalculateTable.ToString(): "计算表", | ||
100 | } | 115 | } |
101 | 116 | ||
102 | var ( | 117 | var ( |
@@ -140,6 +155,14 @@ func (t TableType) ToString() string { | @@ -140,6 +155,14 @@ func (t TableType) ToString() string { | ||
140 | return string(t) | 155 | return string(t) |
141 | } | 156 | } |
142 | 157 | ||
158 | +func (t TableType) TableStatusEditable() bool { | ||
159 | + return t == SchemaTable || t == CalculateItem || t == CalculateTable || t == CalculateSet | ||
160 | +} | ||
161 | + | ||
162 | +func (t TableType) TableHasGroup() bool { | ||
163 | + return t == SchemaTable || t == SubProcessTable || t == CalculateItem || t == CalculateTable || t == CalculateSet | ||
164 | +} | ||
165 | + | ||
143 | type ObjectType TableType | 166 | type ObjectType TableType |
144 | 167 | ||
145 | type OperationType string | 168 | type OperationType string |
@@ -295,6 +318,64 @@ var DBTables = map[int]*Table{ | @@ -295,6 +318,64 @@ var DBTables = map[int]*Table{ | ||
295 | }, | 318 | }, |
296 | }, | 319 | }, |
297 | }, | 320 | }, |
321 | + DBTableFormulaLog.ToInt(): &Table{ | ||
322 | + TableId: 3, | ||
323 | + TableType: ObjectDBTable, | ||
324 | + Name: "日志信息", | ||
325 | + SQLName: "metadata.logs", | ||
326 | + DataFieldIndex: 6, | ||
327 | + PK: &Field{ | ||
328 | + Index: 0, | ||
329 | + Name: "日志ID", | ||
330 | + SQLName: "log_id", | ||
331 | + SQLType: Int.ToString(), | ||
332 | + Flag: PKField, | ||
333 | + }, | ||
334 | + DataFields: []*Field{ | ||
335 | + { | ||
336 | + Index: 1, | ||
337 | + Name: "公式名称", | ||
338 | + SQLName: "object_name", | ||
339 | + SQLType: String.ToString(), | ||
340 | + Flag: MainTableField, | ||
341 | + }, | ||
342 | + { | ||
343 | + Index: 2, | ||
344 | + Name: "类型", | ||
345 | + SQLName: "object_type", | ||
346 | + SQLType: String.ToString(), | ||
347 | + Flag: MainTableField, | ||
348 | + }, | ||
349 | + { | ||
350 | + Index: 3, | ||
351 | + Name: "操作类型", | ||
352 | + SQLName: "operation_type", | ||
353 | + SQLType: String.ToString(), | ||
354 | + Flag: MainTableField, | ||
355 | + }, | ||
356 | + { | ||
357 | + Index: 4, | ||
358 | + Name: "日志内容", | ||
359 | + SQLName: "content", | ||
360 | + SQLType: String.ToString(), | ||
361 | + Flag: MainTableField, | ||
362 | + }, | ||
363 | + { | ||
364 | + Index: 5, | ||
365 | + Name: "操作时间", | ||
366 | + SQLName: "log_time", //"created_at", | ||
367 | + SQLType: String.ToString(), | ||
368 | + Flag: MainTableField, | ||
369 | + }, | ||
370 | + { | ||
371 | + Index: 6, | ||
372 | + Name: "操作人", | ||
373 | + SQLName: "operator_name", | ||
374 | + SQLType: String.ToString(), | ||
375 | + Flag: MainTableField, | ||
376 | + }, | ||
377 | + }, | ||
378 | + }, | ||
298 | } | 379 | } |
299 | 380 | ||
300 | type DBTable int | 381 | type DBTable int |
@@ -306,6 +387,7 @@ func (t DBTable) ToInt() int { | @@ -306,6 +387,7 @@ func (t DBTable) ToInt() int { | ||
306 | const ( | 387 | const ( |
307 | DBTableTableOperateLog DBTable = 1 | 388 | DBTableTableOperateLog DBTable = 1 |
308 | DBTableQuerySetLog DBTable = 2 | 389 | DBTableQuerySetLog DBTable = 2 |
390 | + DBTableFormulaLog DBTable = 3 | ||
309 | ) | 391 | ) |
310 | 392 | ||
311 | const ( | 393 | const ( |
@@ -23,6 +23,8 @@ type Field struct { | @@ -23,6 +23,8 @@ type Field struct { | ||
23 | Description string `json:"description"` | 23 | Description string `json:"description"` |
24 | // 标识 1.主键 2:主表字段 3:手动添加 | 24 | // 标识 1.主键 2:主表字段 3:手动添加 |
25 | Flag int `json:"flag"` | 25 | Flag int `json:"flag"` |
26 | + // 排序 | ||
27 | + Order string `json:"order,omitempty"` | ||
26 | } | 28 | } |
27 | 29 | ||
28 | func (f *Field) Valid() error { | 30 | func (f *Field) Valid() error { |
@@ -21,6 +21,7 @@ type LogEntry struct { | @@ -21,6 +21,7 @@ type LogEntry struct { | ||
21 | // 错误信息 | 21 | // 错误信息 |
22 | Error string `json:"error"` | 22 | Error string `json:"error"` |
23 | ctx *Context `json:"-"` | 23 | ctx *Context `json:"-"` |
24 | + Type string `json:"-"` | ||
24 | } | 25 | } |
25 | 26 | ||
26 | func (l LogEntry) Entry() LogEntry { | 27 | func (l LogEntry) Entry() LogEntry { |
@@ -31,6 +32,10 @@ func (l LogEntry) Context() *Context { | @@ -31,6 +32,10 @@ func (l LogEntry) Context() *Context { | ||
31 | return l.ctx | 32 | return l.ctx |
32 | } | 33 | } |
33 | 34 | ||
35 | +func (l LogEntry) LogType() string { | ||
36 | + return l.Type | ||
37 | +} | ||
38 | + | ||
34 | func (l LogEntry) OperateType() string { | 39 | func (l LogEntry) OperateType() string { |
35 | return l.OperationType | 40 | return l.OperationType |
36 | } | 41 | } |
@@ -82,7 +82,11 @@ func (querySet *QuerySet) Update(queryComponents []*QueryComponent, tableId int) | @@ -82,7 +82,11 @@ func (querySet *QuerySet) Update(queryComponents []*QueryComponent, tableId int) | ||
82 | } | 82 | } |
83 | 83 | ||
84 | func ValidQuerySetType(t string) error { | 84 | func ValidQuerySetType(t string) error { |
85 | - if t == SchemaTable.ToString() || t == SubProcessTable.ToString() { | 85 | + if t == SchemaTable.ToString() || |
86 | + t == SubProcessTable.ToString() || | ||
87 | + t == CalculateItem.ToString() || | ||
88 | + t == CalculateTable.ToString() || | ||
89 | + t == CalculateSet.ToString() { | ||
86 | return nil | 90 | return nil |
87 | } | 91 | } |
88 | return fmt.Errorf("类型有误") | 92 | return fmt.Errorf("类型有误") |
@@ -99,7 +103,9 @@ func (querySet *QuerySet) GetDependencyTables(queryComponents []*QueryComponent) | @@ -99,7 +103,9 @@ func (querySet *QuerySet) GetDependencyTables(queryComponents []*QueryComponent) | ||
99 | set := collection.NewSet() | 103 | set := collection.NewSet() |
100 | 104 | ||
101 | for i := range queryComponents { | 105 | for i := range queryComponents { |
106 | + if queryComponents[i].MasterTable != nil && queryComponents[i].MasterTable.TableId > 0 { | ||
102 | set.AddInt(queryComponents[i].MasterTable.TableId) | 107 | set.AddInt(queryComponents[i].MasterTable.TableId) |
108 | + } | ||
103 | for _, c := range queryComponents[i].Conditions { | 109 | for _, c := range queryComponents[i].Conditions { |
104 | for _, f := range c.FieldLeft.TableFields { | 110 | for _, f := range c.FieldLeft.TableFields { |
105 | set.AddInt(f.TableId) | 111 | set.AddInt(f.TableId) |
@@ -116,6 +122,11 @@ func (querySet *QuerySet) GetDependencyTables(queryComponents []*QueryComponent) | @@ -116,6 +122,11 @@ func (querySet *QuerySet) GetDependencyTables(queryComponents []*QueryComponent) | ||
116 | set.AddInt(f.TableId) | 122 | set.AddInt(f.TableId) |
117 | } | 123 | } |
118 | } | 124 | } |
125 | + if queryComponents[i].Formula != nil { | ||
126 | + for _, f := range queryComponents[i].Formula.TableFields { | ||
127 | + set.AddInt(f.TableId) | ||
128 | + } | ||
129 | + } | ||
119 | } | 130 | } |
120 | res := set.KeysInt() | 131 | res := set.KeysInt() |
121 | sort.Ints(res) | 132 | sort.Ints(res) |
@@ -3,8 +3,11 @@ package domain | @@ -3,8 +3,11 @@ package domain | ||
3 | import "fmt" | 3 | import "fmt" |
4 | 4 | ||
5 | var ( | 5 | var ( |
6 | - SchemaTable TableType = "Schema" | ||
7 | - SubProcessTable TableType = "SubProcess" | 6 | + SchemaTable TableType = "Schema" // 方案 |
7 | + SubProcessTable TableType = "SubProcess" // 子过程 | ||
8 | + CalculateItem TableType = "CalculateItem" // 计算项 | ||
9 | + CalculateTable TableType = "CalculateTable" // 计算表 | ||
10 | + CalculateSet TableType = "CalculateSet" // 计算集 | ||
8 | ) | 11 | ) |
9 | 12 | ||
10 | var ( | 13 | var ( |
@@ -22,12 +25,12 @@ type SelectExprType string | @@ -22,12 +25,12 @@ type SelectExprType string | ||
22 | 25 | ||
23 | type QueryComponent struct { | 26 | type QueryComponent struct { |
24 | Id string `json:"id"` | 27 | Id string `json:"id"` |
25 | - MasterTable QueryComponentTable `json:"masterTable"` | 28 | + MasterTable *QueryComponentTable `json:"masterTable"` |
26 | Conditions []ConditionExpr `json:"conditions"` | 29 | Conditions []ConditionExpr `json:"conditions"` |
27 | - JoinTables []QueryComponentTable `json:"-"` //joinTables | ||
28 | Selects []SelectExprGroup `json:"selects"` | 30 | Selects []SelectExprGroup `json:"selects"` |
29 | - SelectFromTables []QueryComponentTable `json:"-"` //selectTables | ||
30 | Description string `json:"description"` | 31 | Description string `json:"description"` |
32 | + Formula *FieldFormulaExpr `json:"formula"` | ||
33 | + Aggregation *AggregationRule `json:"aggregation"` | ||
31 | } | 34 | } |
32 | 35 | ||
33 | func (qc QueryComponent) AllSelectExpr() []SelectExpr { | 36 | func (qc QueryComponent) AllSelectExpr() []SelectExpr { |
@@ -59,6 +62,10 @@ func (c ConditionExpr) ExprHuman() string { | @@ -59,6 +62,10 @@ func (c ConditionExpr) ExprHuman() string { | ||
59 | return c.FieldLeft.ExprHuman + c.OperatorSymbol + c.FieldRight.ExprHuman | 62 | return c.FieldLeft.ExprHuman + c.OperatorSymbol + c.FieldRight.ExprHuman |
60 | } | 63 | } |
61 | 64 | ||
65 | +type FieldFormulaExpr struct { | ||
66 | + FieldExpr | ||
67 | +} | ||
68 | + | ||
62 | type SelectExpr struct { // 查询表达式 | 69 | type SelectExpr struct { // 查询表达式 |
63 | Id string `json:"id"` | 70 | Id string `json:"id"` |
64 | FieldLeft FieldExpr `json:"fieldLeft"` | 71 | FieldLeft FieldExpr `json:"fieldLeft"` |
@@ -129,8 +136,8 @@ type Join struct { | @@ -129,8 +136,8 @@ type Join struct { | ||
129 | On SelectExpr | 136 | On SelectExpr |
130 | } | 137 | } |
131 | 138 | ||
132 | -func NewQueryComponentTable(t *Table) QueryComponentTable { | ||
133 | - return QueryComponentTable{ | 139 | +func NewQueryComponentTable(t *Table) *QueryComponentTable { |
140 | + return &QueryComponentTable{ | ||
134 | TableId: t.TableId, | 141 | TableId: t.TableId, |
135 | TableType: t.TableType, | 142 | TableType: t.TableType, |
136 | Name: t.Name, | 143 | Name: t.Name, |
1 | +package domain | ||
2 | + | ||
3 | +import ( | ||
4 | + "bytes" | ||
5 | + "fmt" | ||
6 | +) | ||
7 | + | ||
8 | +type AggregationRule struct { | ||
9 | + Aggregation | ||
10 | +} | ||
11 | + | ||
12 | +type Aggregation struct { | ||
13 | + // 行 | ||
14 | + RowFields []*AggregationField `json:"rowFields"` | ||
15 | + // 值 | ||
16 | + ValueFields []*AggregationField `json:"valueFields"` | ||
17 | + // 选择列表 【字段名称】 | ||
18 | + SelectFields []string `json:"selectFields"` | ||
19 | +} | ||
20 | + | ||
21 | +type AggregationField struct { | ||
22 | + Id string `json:"id"` | ||
23 | + Field *Field `json:"field"` | ||
24 | + DisplayName string `json:"displayName"` | ||
25 | + AggregationFlag string `json:"aggregationFlag"` // 行:row 列:column 值:value | ||
26 | + Order string `json:"order"` // 降序:desc 升序asc 默认:"" 无排序 | ||
27 | + Expr FieldExpr `json:"expr"` | ||
28 | +} | ||
29 | + | ||
30 | +func (ar *AggregationRule) Fields() []*Field { | ||
31 | + fields := make([]*Field, 0) | ||
32 | + for _, f := range ar.RowFields { | ||
33 | + fields = append(fields, f.Field) | ||
34 | + } | ||
35 | + for _, f := range ar.ValueFields { | ||
36 | + fields = append(fields, f.Field) | ||
37 | + } | ||
38 | + return fields | ||
39 | +} | ||
40 | + | ||
41 | +func (ar *AggregationRule) AggregationFields() []*AggregationField { | ||
42 | + fields := make([]*AggregationField, 0) | ||
43 | + for _, f := range ar.RowFields { | ||
44 | + fields = append(fields, f) | ||
45 | + } | ||
46 | + for _, f := range ar.ValueFields { | ||
47 | + fields = append(fields, f) | ||
48 | + } | ||
49 | + return fields | ||
50 | +} | ||
51 | + | ||
52 | +func (ar *AggregationRule) OrderFields() []*Field { | ||
53 | + aggregationFields := ar.AggregationFields() | ||
54 | + var fields = make([]*Field, 0) | ||
55 | + for _, f := range aggregationFields { | ||
56 | + if f.Order != "" { | ||
57 | + copyField := f.Field.Copy() | ||
58 | + copyField.Order = f.Order | ||
59 | + fields = append(fields, copyField) | ||
60 | + } | ||
61 | + } | ||
62 | + return fields | ||
63 | +} | ||
64 | + | ||
65 | +func (ar *AggregationField) Diff(c *AggregationField) bool { | ||
66 | + if ar.Expr.ExprSql != c.Expr.ExprSql { | ||
67 | + return true | ||
68 | + } | ||
69 | + if ar.Order != c.Order { | ||
70 | + return true | ||
71 | + } | ||
72 | + if ar.AggregationFlag != c.AggregationFlag { | ||
73 | + return true | ||
74 | + } | ||
75 | + return false | ||
76 | +} | ||
77 | + | ||
78 | +func (ar *AggregationField) Info() string { | ||
79 | + buf := bytes.NewBuffer(nil) | ||
80 | + buf.WriteString("(") | ||
81 | + buf.WriteString(fmt.Sprintf("%s|", ar.DisplayName)) | ||
82 | + buf.WriteString(fmt.Sprintf("%s,", ar.Expr.ExprHuman)) | ||
83 | + if ar.AggregationFlag == "row" { | ||
84 | + buf.WriteString("分组,") | ||
85 | + } else { | ||
86 | + buf.WriteString("不分组,") | ||
87 | + } | ||
88 | + if ar.Order == "asc" { | ||
89 | + buf.WriteString("升序") | ||
90 | + } else if ar.Order == "desc" { | ||
91 | + buf.WriteString("降序") | ||
92 | + } else { | ||
93 | + buf.WriteString("默认") | ||
94 | + } | ||
95 | + buf.WriteString(")") | ||
96 | + return buf.String() | ||
97 | +} |
@@ -27,6 +27,8 @@ type Table struct { | @@ -27,6 +27,8 @@ type Table struct { | ||
27 | DataFields []*Field `json:"dataFields"` | 27 | DataFields []*Field `json:"dataFields"` |
28 | // 手动添加的列 | 28 | // 手动添加的列 |
29 | ManualFields []*Field `json:"manualFields"` | 29 | ManualFields []*Field `json:"manualFields"` |
30 | + // 默认排序列 | ||
31 | + //OrderFields []*Field `json:"orderFields"` | ||
30 | // 创建时间 | 32 | // 创建时间 |
31 | CreatedAt time.Time `json:"createdAt"` | 33 | CreatedAt time.Time `json:"createdAt"` |
32 | // 更新时间 | 34 | // 更新时间 |
@@ -104,7 +104,7 @@ func NewFormulaCondition(queryComponent *domain.QueryComponent) FormulaCondition | @@ -104,7 +104,7 @@ func NewFormulaCondition(queryComponent *domain.QueryComponent) FormulaCondition | ||
104 | return res | 104 | return res |
105 | } | 105 | } |
106 | 106 | ||
107 | -func NewFormulaSelectFields(t domain.QueryComponentTable) FormulaSelectFields { | 107 | +func NewFormulaSelectFields(t *domain.QueryComponentTable) FormulaSelectFields { |
108 | var res = FormulaSelectFields{ | 108 | var res = FormulaSelectFields{ |
109 | DatabaseTableName: t.SQLName, | 109 | DatabaseTableName: t.SQLName, |
110 | FieldSchemas: ToFieldSchemas(t.Fields), | 110 | FieldSchemas: ToFieldSchemas(t.Fields), |
@@ -7,6 +7,7 @@ import ( | @@ -7,6 +7,7 @@ import ( | ||
7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
8 | "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" |
9 | "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" | ||
10 | ) | 11 | ) |
11 | 12 | ||
12 | type ByteCoreService struct { | 13 | type ByteCoreService struct { |
@@ -128,6 +129,24 @@ func (ptr *ByteCoreService) FieldOptionalValues(param domain.ReqFieldOptionalVal | @@ -128,6 +129,24 @@ func (ptr *ByteCoreService) FieldOptionalValues(param domain.ReqFieldOptionalVal | ||
128 | 129 | ||
129 | func (ptr *ByteCoreService) FormulasGenerate(param domain.ReqFormulasGenerate) (*domain.DataFormulasGenerate, error) { | 130 | func (ptr *ByteCoreService) FormulasGenerate(param domain.ReqFormulasGenerate) (*domain.DataFormulasGenerate, error) { |
130 | apiByteLib := bytelib.NewApiByteLib(constant.BYTE_CORE_HOST) | 131 | apiByteLib := bytelib.NewApiByteLib(constant.BYTE_CORE_HOST) |
132 | + if param.QuerySet.Type == domain.CalculateItem.ToString() { | ||
133 | + if err := starrocks.Exec(starrocks.DB, | ||
134 | + starrocks.CreateViewSql(param.Table.SQLName, param.Table.DataFields, | ||
135 | + starrocks.CalculateItemViewSql(¶m.QueryComponents[0].Formula.FieldExpr), | ||
136 | + )); err != nil { | ||
137 | + return nil, err | ||
138 | + } | ||
139 | + return &domain.DataFormulasGenerate{}, nil | ||
140 | + } | ||
141 | + if param.QuerySet.Type == domain.CalculateTable.ToString() { | ||
142 | + if err := starrocks.Exec(starrocks.DB, | ||
143 | + starrocks.CreateViewSql(param.Table.SQLName, param.Table.DataFields, | ||
144 | + starrocks.CalculateTableViewSql(param.QueryComponents[0].MasterTable.SQLName, ¶m.QueryComponents[0].Aggregation.Aggregation), | ||
145 | + )); err != nil { | ||
146 | + return nil, err | ||
147 | + } | ||
148 | + return &domain.DataFormulasGenerate{}, nil | ||
149 | + } | ||
131 | return apiByteLib.FormulasGenerate(param) | 150 | return apiByteLib.FormulasGenerate(param) |
132 | } | 151 | } |
133 | 152 |
@@ -137,6 +137,9 @@ func NewTable(tableType domain.TableType, fileName string, dataFields []*domain. | @@ -137,6 +137,9 @@ func NewTable(tableType domain.TableType, fileName string, dataFields []*domain. | ||
137 | table.Name = fileName | 137 | table.Name = fileName |
138 | table.SQLName = pin(fileName) //SQLTableName() | 138 | table.SQLName = pin(fileName) //SQLTableName() |
139 | table.PK = PK() | 139 | table.PK = PK() |
140 | + if table.TableType == domain.CalculateTable.ToString() || table.TableType == domain.CalculateItem.ToString() { | ||
141 | + table.PK = nil | ||
142 | + } | ||
140 | table.DataFieldIndex = len(dataFields) | 143 | table.DataFieldIndex = len(dataFields) |
141 | for i, field := range dataFields { | 144 | for i, field := range dataFields { |
142 | table.DataFields = append(table.DataFields, DataField(field.Name, field.SQLType, domain.MainTableField, i+1)) | 145 | table.DataFields = append(table.DataFields, DataField(field.Name, field.SQLType, domain.MainTableField, i+1)) |
@@ -156,6 +159,9 @@ func NewCopyTable(tableType domain.TableType, fileName string, dataFields []*dom | @@ -156,6 +159,9 @@ func NewCopyTable(tableType domain.TableType, fileName string, dataFields []*dom | ||
156 | table.Name = fileName | 159 | table.Name = fileName |
157 | table.SQLName = pin(fileName) //SQLTableName() | 160 | table.SQLName = pin(fileName) //SQLTableName() |
158 | table.PK = PK() | 161 | table.PK = PK() |
162 | + if table.TableType == domain.CalculateTable.ToString() || table.TableType == domain.CalculateItem.ToString() { | ||
163 | + table.PK = nil | ||
164 | + } | ||
159 | table.DataFieldIndex = len(dataFields) | 165 | table.DataFieldIndex = len(dataFields) |
160 | table.DataFields = dataFields | 166 | table.DataFields = dataFields |
161 | table.ManualFields = make([]*domain.Field, 0) | 167 | table.ManualFields = make([]*domain.Field, 0) |
@@ -49,6 +49,9 @@ func (ptr *PGLogService) Log(logType domain.LogType, sourceId int, logEntry Log) | @@ -49,6 +49,9 @@ func (ptr *PGLogService) Log(logType domain.LogType, sourceId int, logEntry Log) | ||
49 | if entry.OperationType == domain.UnKnown.ToString() { | 49 | if entry.OperationType == domain.UnKnown.ToString() { |
50 | return nil | 50 | return nil |
51 | } | 51 | } |
52 | + if logEntry.LogType() != "" { | ||
53 | + log.LogType = logEntry.LogType() | ||
54 | + } | ||
52 | 55 | ||
53 | if v, ok := logEntry.Context().GetValue(domain.ContextWithLogLevel); ok { | 56 | if v, ok := logEntry.Context().GetValue(domain.ContextWithLogLevel); ok { |
54 | log.Entry.Level = string(v.(domain.LogLevel)) | 57 | log.Entry.Level = string(v.(domain.LogLevel)) |
@@ -83,6 +86,7 @@ type Log interface { | @@ -83,6 +86,7 @@ type Log interface { | ||
83 | Entry() domain.LogEntry | 86 | Entry() domain.LogEntry |
84 | Context() *domain.Context | 87 | Context() *domain.Context |
85 | OperateType() string | 88 | OperateType() string |
89 | + LogType() string | ||
86 | } | 90 | } |
87 | 91 | ||
88 | var _ Log = (*FileUploadSuccessLog)(nil) | 92 | var _ Log = (*FileUploadSuccessLog)(nil) |
@@ -351,14 +355,31 @@ func (l *CreateQuerySetLog) OperateType() string { | @@ -351,14 +355,31 @@ func (l *CreateQuerySetLog) OperateType() string { | ||
351 | if l.Qs.Type == domain.SubProcessTable.ToString() && l.Qs.Flag == domain.FlagSet { | 355 | if l.Qs.Type == domain.SubProcessTable.ToString() && l.Qs.Flag == domain.FlagSet { |
352 | return domain.CreateSubProcess.ToString() | 356 | return domain.CreateSubProcess.ToString() |
353 | } | 357 | } |
358 | + if l.Qs.Type == domain.CalculateItem.ToString() && l.Qs.Flag == domain.FlagSet { | ||
359 | + return domain.CreateFormula.ToString() | ||
360 | + } | ||
361 | + if l.Qs.Type == domain.CalculateTable.ToString() && l.Qs.Flag == domain.FlagSet { | ||
362 | + return domain.CreateFormula.ToString() | ||
363 | + } | ||
364 | + if l.Qs.Type == domain.CalculateSet.ToString() && l.Qs.Flag == domain.FlagSet { | ||
365 | + return domain.CreateFormula.ToString() | ||
366 | + } | ||
354 | return domain.UnKnown.ToString() | 367 | return domain.UnKnown.ToString() |
355 | } | 368 | } |
356 | 369 | ||
370 | +func (l *CreateQuerySetLog) LogType() string { | ||
371 | + if l.Qs.Type == domain.SchemaTable.ToString() || l.Qs.Type == domain.SubProcessTable.ToString() { | ||
372 | + return domain.QuerySetLog.ToString() | ||
373 | + } | ||
374 | + return domain.FormulaLog.ToString() | ||
375 | +} | ||
376 | + | ||
357 | func (l *CreateQuerySetLog) Content() string { | 377 | func (l *CreateQuerySetLog) Content() string { |
358 | return "新增成功" | 378 | return "新增成功" |
359 | } | 379 | } |
360 | 380 | ||
361 | type RenameQuerySetLog struct { | 381 | type RenameQuerySetLog struct { |
382 | + Qs *domain.QuerySet | ||
362 | domain.LogEntry | 383 | domain.LogEntry |
363 | OldName string | 384 | OldName string |
364 | NewName string | 385 | NewName string |
@@ -368,6 +389,13 @@ func (l *RenameQuerySetLog) OperateType() string { | @@ -368,6 +389,13 @@ func (l *RenameQuerySetLog) OperateType() string { | ||
368 | return domain.RenameQuerySet.ToString() | 389 | return domain.RenameQuerySet.ToString() |
369 | } | 390 | } |
370 | 391 | ||
392 | +func (l *RenameQuerySetLog) LogType() string { | ||
393 | + if l.Qs.Type == domain.SchemaTable.ToString() || l.Qs.Type == domain.SubProcessTable.ToString() { | ||
394 | + return domain.QuerySetLog.ToString() | ||
395 | + } | ||
396 | + return domain.FormulaLog.ToString() | ||
397 | +} | ||
398 | + | ||
371 | func (l *RenameQuerySetLog) Content() string { | 399 | func (l *RenameQuerySetLog) Content() string { |
372 | return fmt.Sprintf(`"%s"重命名为"%v"`, l.OldName, l.NewName) | 400 | return fmt.Sprintf(`"%s"重命名为"%v"`, l.OldName, l.NewName) |
373 | } | 401 | } |
@@ -384,6 +412,17 @@ func (l *DeleteQuerySetLog) OperateType() string { | @@ -384,6 +412,17 @@ func (l *DeleteQuerySetLog) OperateType() string { | ||
384 | return domain.DeleteQuerySet.ToString() | 412 | return domain.DeleteQuerySet.ToString() |
385 | } | 413 | } |
386 | 414 | ||
415 | +func (l *DeleteQuerySetLog) LogType() string { | ||
416 | + if len(l.DeleteList) == 0 { | ||
417 | + return "" | ||
418 | + } | ||
419 | + qs := l.DeleteList[0] | ||
420 | + if qs.Type == domain.SchemaTable.ToString() || qs.Type == domain.SubProcessTable.ToString() { | ||
421 | + return domain.QuerySetLog.ToString() | ||
422 | + } | ||
423 | + return domain.FormulaLog.ToString() | ||
424 | +} | ||
425 | + | ||
387 | func (l *DeleteQuerySetLog) Content() string { | 426 | func (l *DeleteQuerySetLog) Content() string { |
388 | names := make([]string, 0) | 427 | names := make([]string, 0) |
389 | for i := range l.DeleteList { | 428 | for i := range l.DeleteList { |
@@ -406,9 +445,20 @@ func (l *CopyQuerySetLog) OperateType() string { | @@ -406,9 +445,20 @@ func (l *CopyQuerySetLog) OperateType() string { | ||
406 | return domain.CopyQuerySet.ToString() | 445 | return domain.CopyQuerySet.ToString() |
407 | } | 446 | } |
408 | 447 | ||
448 | +func (l *CopyQuerySetLog) LogType() string { | ||
449 | + qs := l.From | ||
450 | + if qs.Type == domain.SchemaTable.ToString() || qs.Type == domain.SubProcessTable.ToString() { | ||
451 | + return domain.QuerySetLog.ToString() | ||
452 | + } | ||
453 | + return domain.FormulaLog.ToString() | ||
454 | +} | ||
455 | + | ||
409 | func (l *CopyQuerySetLog) Content() string { | 456 | func (l *CopyQuerySetLog) Content() string { |
410 | - return fmt.Sprintf(`%s"%s"复制为%s"%s""`, domain.EnumsDescription(domain.ObjectTypeMap, l.From.Type), l.From.Name, | 457 | + if l.LogType() == domain.QuerySetLog.ToString() { |
458 | + return fmt.Sprintf(`%s"%s"复制为%s"%s"`, domain.EnumsDescription(domain.ObjectTypeMap, l.From.Type), l.From.Name, | ||
411 | domain.EnumsDescription(domain.ObjectTypeMap, l.To.Type), l.To.Name) | 459 | domain.EnumsDescription(domain.ObjectTypeMap, l.To.Type), l.To.Name) |
460 | + } | ||
461 | + return fmt.Sprintf(`"%s"复制为"%s"`, l.From.Name, l.To.Name) | ||
412 | } | 462 | } |
413 | 463 | ||
414 | type EditQuerySetConditionLog struct { | 464 | type EditQuerySetConditionLog struct { |
@@ -460,3 +510,25 @@ func (l *EditSelectConditionLog) Content() string { | @@ -460,3 +510,25 @@ func (l *EditSelectConditionLog) Content() string { | ||
460 | } | 510 | } |
461 | return "删除拆分规则:" + strings.Join(l.Sources, ";") | 511 | return "删除拆分规则:" + strings.Join(l.Sources, ";") |
462 | } | 512 | } |
513 | + | ||
514 | +type EditFormulaLog struct { | ||
515 | + domain.LogEntry | ||
516 | + OperationType domain.OperationType // 编辑类型 1:add 2.edit 3.delete | ||
517 | + Old string | ||
518 | + New string | ||
519 | + Msg string | ||
520 | +} | ||
521 | + | ||
522 | +func (l *EditFormulaLog) OperateType() string { | ||
523 | + return l.OperationType.ToString() | ||
524 | +} | ||
525 | + | ||
526 | +func (l *EditFormulaLog) Content() string { | ||
527 | + if len(l.Msg) > 0 { | ||
528 | + return l.Msg | ||
529 | + } | ||
530 | + if len(l.Old) == 0 { | ||
531 | + return fmt.Sprintf("修改为 %v", l.New) | ||
532 | + } | ||
533 | + return fmt.Sprintf("%v 修改为 %v", l.Old, l.New) | ||
534 | +} |
@@ -7,6 +7,7 @@ import ( | @@ -7,6 +7,7 @@ import ( | ||
7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/dao" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/dao" |
8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" | 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis" |
9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository" | 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository" |
10 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks" | ||
10 | "strings" | 11 | "strings" |
11 | "time" | 12 | "time" |
12 | ) | 13 | ) |
@@ -94,7 +95,20 @@ func (ptr *QuerySetService) Update(ctx *domain.Context, querySetId int, queryCom | @@ -94,7 +95,20 @@ func (ptr *QuerySetService) Update(ctx *domain.Context, querySetId int, queryCom | ||
94 | if err != nil { | 95 | if err != nil { |
95 | return err | 96 | return err |
96 | } | 97 | } |
98 | + if qs.Type == domain.SchemaTable.ToString() || qs.Type == domain.SubProcessTable.ToString() { | ||
99 | + return ptr.UpdateDefault(ctx, qs, queryComponents) | ||
100 | + } | ||
101 | + if qs.Type == domain.CalculateItem.ToString() { | ||
102 | + return ptr.UpdateCalculateItem(ctx, qs, queryComponents) | ||
103 | + } | ||
104 | + if qs.Type == domain.CalculateTable.ToString() { | ||
105 | + return ptr.UpdateCalculateTable(ctx, qs, queryComponents) | ||
106 | + } | ||
107 | + return nil | ||
108 | +} | ||
97 | 109 | ||
110 | +func (ptr *QuerySetService) UpdateDefault(ctx *domain.Context, qs *domain.QuerySet, queryComponents []*domain.QueryComponent) error { | ||
111 | + querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) | ||
98 | // 生成Table | 112 | // 生成Table |
99 | masterTable := queryComponents[0].MasterTable | 113 | masterTable := queryComponents[0].MasterTable |
100 | table, err := ptr.CreateOrUpdateQuerySetTable(ctx, qs, masterTable, queryComponents) | 114 | table, err := ptr.CreateOrUpdateQuerySetTable(ctx, qs, masterTable, queryComponents) |
@@ -137,6 +151,90 @@ func (ptr *QuerySetService) Update(ctx *domain.Context, querySetId int, queryCom | @@ -137,6 +151,90 @@ func (ptr *QuerySetService) Update(ctx *domain.Context, querySetId int, queryCom | ||
137 | return nil | 151 | return nil |
138 | } | 152 | } |
139 | 153 | ||
154 | +func (ptr *QuerySetService) UpdateCalculateItem(ctx *domain.Context, qs *domain.QuerySet, queryComponents []*domain.QueryComponent) error { | ||
155 | + querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) | ||
156 | + // 生成Table | ||
157 | + //masterTable := queryComponents[0].MasterTable | ||
158 | + table, err := ptr.CreateOrUpdateCalculateItemTable(ctx, qs, nil, queryComponents) | ||
159 | + if err != nil { | ||
160 | + return err | ||
161 | + } | ||
162 | + | ||
163 | + if err = ptr.validQueryComponents(queryComponents); err != nil { | ||
164 | + return err | ||
165 | + } | ||
166 | + | ||
167 | + // 调用底层的组装sql | ||
168 | + _, err = ByteCore.FormulasGenerate(domain.ReqFormulasGenerate{ | ||
169 | + QuerySet: qs, | ||
170 | + Table: table, | ||
171 | + QueryComponents: queryComponents, | ||
172 | + }) | ||
173 | + if err != nil { | ||
174 | + return err | ||
175 | + } | ||
176 | + //if err = starrocks.Exec(starrocks.DB, | ||
177 | + // starrocks.CreateViewSql(table.SQLName, table.DataFields, | ||
178 | + // starrocks.CalculateItemViewSql(&queryComponents[0].Formula.FieldExpr), | ||
179 | + // )); err != nil { | ||
180 | + // return err | ||
181 | + //} | ||
182 | + | ||
183 | + // 生成日志 | ||
184 | + if err = ptr.UpdateQuerySetLog(ctx, qs, queryComponents); err != nil { | ||
185 | + return err | ||
186 | + } | ||
187 | + // 保存 | ||
188 | + qs.Update(queryComponents, table.TableId) | ||
189 | + _, err = querySetRepository.Save(qs) | ||
190 | + if err != nil { | ||
191 | + return err | ||
192 | + } | ||
193 | + return nil | ||
194 | +} | ||
195 | + | ||
196 | +func (ptr *QuerySetService) UpdateCalculateTable(ctx *domain.Context, qs *domain.QuerySet, queryComponents []*domain.QueryComponent) error { | ||
197 | + querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) | ||
198 | + // 生成Table | ||
199 | + masterTable := queryComponents[0].MasterTable | ||
200 | + table, err := ptr.CreateOrUpdateCalculateTable(ctx, qs, masterTable, queryComponents) | ||
201 | + if err != nil { | ||
202 | + return err | ||
203 | + } | ||
204 | + | ||
205 | + if err = ptr.validQueryComponents(queryComponents); err != nil { | ||
206 | + return err | ||
207 | + } | ||
208 | + | ||
209 | + // 调用底层的组装sql | ||
210 | + _, err = ByteCore.FormulasGenerate(domain.ReqFormulasGenerate{ | ||
211 | + QuerySet: qs, | ||
212 | + Table: table, | ||
213 | + QueryComponents: queryComponents, | ||
214 | + }) | ||
215 | + if err != nil { | ||
216 | + return err | ||
217 | + } | ||
218 | + //if err = starrocks.Exec(starrocks.DB, | ||
219 | + // starrocks.CreateViewSql(table.SQLName, table.DataFields, | ||
220 | + // starrocks.CalculateTableViewSql(queryComponents[0].MasterTable.SQLName, &queryComponents[0].Aggregation.Aggregation), | ||
221 | + // )); err != nil { | ||
222 | + // return err | ||
223 | + //} | ||
224 | + | ||
225 | + // 生成日志 | ||
226 | + if err = ptr.UpdateQuerySetLog(ctx, qs, queryComponents); err != nil { | ||
227 | + return err | ||
228 | + } | ||
229 | + // 保存 | ||
230 | + qs.Update(queryComponents, table.TableId) | ||
231 | + _, err = querySetRepository.Save(qs) | ||
232 | + if err != nil { | ||
233 | + return err | ||
234 | + } | ||
235 | + return nil | ||
236 | +} | ||
237 | + | ||
140 | func (ptr *QuerySetService) PreviewPrepare(ctx *domain.Context, querySetId int, queryComponents []*domain.QueryComponent) (*domain.Table, error) { | 238 | func (ptr *QuerySetService) PreviewPrepare(ctx *domain.Context, querySetId int, queryComponents []*domain.QueryComponent) (*domain.Table, error) { |
141 | querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) | 239 | querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) |
142 | querySet, err := querySetRepository.FindOne(map[string]interface{}{"querySetId": querySetId}) | 240 | querySet, err := querySetRepository.FindOne(map[string]interface{}{"querySetId": querySetId}) |
@@ -159,14 +257,24 @@ func (ptr *QuerySetService) PreviewPrepare(ctx *domain.Context, querySetId int, | @@ -159,14 +257,24 @@ func (ptr *QuerySetService) PreviewPrepare(ctx *domain.Context, querySetId int, | ||
159 | foundMasterTable *domain.Table | 257 | foundMasterTable *domain.Table |
160 | ) | 258 | ) |
161 | // 生成Table | 259 | // 生成Table |
162 | - masterTable := queryComponents[0].MasterTable | 260 | + var fields = make([]*domain.Field, 0) |
163 | dependencyTables := querySet.GetDependencyTables(queryComponents) | 261 | dependencyTables := querySet.GetDependencyTables(queryComponents) |
262 | + if querySet.Type == domain.CalculateTable.ToString() { | ||
263 | + aggregationFields := append(queryComponents[0].Aggregation.RowFields, queryComponents[0].Aggregation.ValueFields...) | ||
264 | + for index, f := range aggregationFields { | ||
265 | + fields = append(fields, DataField(f.DisplayName, f.Field.SQLType, domain.MainTableField, index)) | ||
266 | + } | ||
267 | + } else { | ||
268 | + masterTable := queryComponents[0].MasterTable | ||
164 | foundMasterTable, err = tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableId": masterTable.TableId}) | 269 | foundMasterTable, err = tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableId": masterTable.TableId}) |
165 | if err != nil { | 270 | if err != nil { |
166 | return nil, err | 271 | return nil, err |
167 | } | 272 | } |
168 | masterTable = domain.NewQueryComponentTable(foundMasterTable) | 273 | masterTable = domain.NewQueryComponentTable(foundMasterTable) |
169 | - var table *domain.Table = NewCopyTable(domain.TableType(domain.TemporaryTable), querySet.Name, domain.RangeFields(masterTable.Fields, domain.ChangeFieldFlag), 0). | 274 | + fields = masterTable.Fields |
275 | + } | ||
276 | + | ||
277 | + var table *domain.Table = NewCopyTable(domain.TableType(domain.TemporaryTable), querySet.Name, domain.RangeFields(fields, domain.ChangeFieldFlag), 0). | ||
170 | WithContext(ctx). | 278 | WithContext(ctx). |
171 | WithPrefix(strings.ToLower(string(domain.TemporaryTable))) | 279 | WithPrefix(strings.ToLower(string(domain.TemporaryTable))) |
172 | // 循环依赖判断 | 280 | // 循环依赖判断 |
@@ -258,7 +366,12 @@ func (ptr *QuerySetService) UpdateQuerySetLog(ctx *domain.Context, querySet *dom | @@ -258,7 +366,12 @@ func (ptr *QuerySetService) UpdateQuerySetLog(ctx *domain.Context, querySet *dom | ||
258 | if logs := selectsEditLog(ctx, querySet, queryComponents); len(logs) > 0 { | 366 | if logs := selectsEditLog(ctx, querySet, queryComponents); len(logs) > 0 { |
259 | res = append(res, logs...) | 367 | res = append(res, logs...) |
260 | } | 368 | } |
261 | - | 369 | + if logs := formulaEditLog(ctx, querySet, queryComponents); len(logs) > 0 { |
370 | + res = append(res, logs...) | ||
371 | + } | ||
372 | + if logs := aggregationEditLog(ctx, querySet, queryComponents); len(logs) > 0 { | ||
373 | + res = append(res, logs...) | ||
374 | + } | ||
262 | for _, l := range res { | 375 | for _, l := range res { |
263 | FastLog(ptr.transactionContext, l.LogType, l.SourceId, l.LogEntry) | 376 | FastLog(ptr.transactionContext, l.LogType, l.SourceId, l.LogEntry) |
264 | } | 377 | } |
@@ -350,23 +463,6 @@ func conditionsEditLog(ctx *domain.Context, querySet *domain.QuerySet, queryComp | @@ -350,23 +463,6 @@ func conditionsEditLog(ctx *domain.Context, querySet *domain.QuerySet, queryComp | ||
350 | return res | 463 | return res |
351 | } | 464 | } |
352 | 465 | ||
353 | -func queryComponentsHasEdit(ctx *domain.Context, querySet *domain.QuerySet, queryComponents []*domain.QueryComponent) bool { | ||
354 | - logs := selectsEditLog(ctx, querySet, queryComponents) | ||
355 | - if len(logs) > 0 { | ||
356 | - return true | ||
357 | - } | ||
358 | - logs = conditionsEditLog(ctx, querySet, queryComponents) | ||
359 | - if len(logs) > 0 { | ||
360 | - return true | ||
361 | - } | ||
362 | - for _, item := range queryComponents { | ||
363 | - if len(item.Id) == 0 { | ||
364 | - return true | ||
365 | - } | ||
366 | - } | ||
367 | - return false | ||
368 | -} | ||
369 | - | ||
370 | func selectsEditLog(ctx *domain.Context, querySet *domain.QuerySet, queryComponents []*domain.QueryComponent) []FastSourceLog { | 466 | func selectsEditLog(ctx *domain.Context, querySet *domain.QuerySet, queryComponents []*domain.QueryComponent) []FastSourceLog { |
371 | var res = make([]FastSourceLog, 0) | 467 | var res = make([]FastSourceLog, 0) |
372 | oldQCs := domain.QueryComponentsToMapById(querySet.QueryComponents) | 468 | oldQCs := domain.QueryComponentsToMapById(querySet.QueryComponents) |
@@ -451,7 +547,88 @@ func selectsEditLog(ctx *domain.Context, querySet *domain.QuerySet, queryCompone | @@ -451,7 +547,88 @@ func selectsEditLog(ctx *domain.Context, querySet *domain.QuerySet, queryCompone | ||
451 | return res | 547 | return res |
452 | } | 548 | } |
453 | 549 | ||
454 | -func (ptr *QuerySetService) CreateOrUpdateQuerySetTable(ctx *domain.Context, querySet *domain.QuerySet, masterTable domain.QueryComponentTable, queryComponents []*domain.QueryComponent) (*domain.Table, error) { | 550 | +func formulaEditLog(ctx *domain.Context, querySet *domain.QuerySet, queryComponents []*domain.QueryComponent) []FastSourceLog { |
551 | + var res = make([]FastSourceLog, 0) | ||
552 | + sourceId := querySet.QuerySetId | ||
553 | + entry := domain.NewLogEntry(querySet.Name, querySet.Type, domain.UnKnown, ctx) | ||
554 | + | ||
555 | + if len(queryComponents) > 0 && len(querySet.QueryComponents) > 0 { | ||
556 | + oldQC := querySet.QueryComponents[0] | ||
557 | + newQC := queryComponents[0] | ||
558 | + if oldQC.Formula == nil || newQC.Formula == nil { | ||
559 | + return res | ||
560 | + } | ||
561 | + if oldQC.Formula.ExprSql != newQC.Formula.ExprSql { | ||
562 | + res = append(res, NewFastSourceLog(domain.QuerySetLog, sourceId, &EditFormulaLog{ | ||
563 | + LogEntry: entry, | ||
564 | + OperationType: domain.EditCalculateItem, | ||
565 | + Old: oldQC.Formula.ExprHuman, | ||
566 | + New: newQC.Formula.ExprHuman, | ||
567 | + })) | ||
568 | + } | ||
569 | + } | ||
570 | + return res | ||
571 | +} | ||
572 | + | ||
573 | +func aggregationEditLog(ctx *domain.Context, querySet *domain.QuerySet, queryComponents []*domain.QueryComponent) []FastSourceLog { | ||
574 | + var res = make([]FastSourceLog, 0) | ||
575 | + sourceId := querySet.QuerySetId | ||
576 | + entry := domain.NewLogEntry(querySet.Name, querySet.Type, domain.UnKnown, ctx) | ||
577 | + | ||
578 | + if len(queryComponents) > 0 && len(querySet.QueryComponents) > 0 { | ||
579 | + oldQC := querySet.QueryComponents[0] | ||
580 | + newQC := queryComponents[0] | ||
581 | + if oldQC.Aggregation == nil || newQC.Aggregation == nil { | ||
582 | + return res | ||
583 | + } | ||
584 | + | ||
585 | + mapOldAgFields := make(map[string]*domain.AggregationField) | ||
586 | + for _, f := range oldQC.Aggregation.AggregationFields() { | ||
587 | + mapOldAgFields[f.DisplayName] = f | ||
588 | + } | ||
589 | + changList := make([]string, 0) | ||
590 | + for _, f := range newQC.Aggregation.AggregationFields() { | ||
591 | + if v, ok := mapOldAgFields[f.DisplayName]; ok { | ||
592 | + if f.Diff(v) { | ||
593 | + changList = append(changList, fmt.Sprintf("%s修改为%s", v.Info(), f.Info())) | ||
594 | + } | ||
595 | + } | ||
596 | + } | ||
597 | + | ||
598 | + if len(changList) > 0 { | ||
599 | + res = append(res, NewFastSourceLog(domain.QuerySetLog, sourceId, &EditFormulaLog{ | ||
600 | + LogEntry: entry, | ||
601 | + OperationType: domain.EditCalculateTable, | ||
602 | + Msg: strings.Join(changList, ";"), | ||
603 | + })) | ||
604 | + } | ||
605 | + } | ||
606 | + return res | ||
607 | +} | ||
608 | + | ||
609 | +func queryComponentsHasEdit(ctx *domain.Context, querySet *domain.QuerySet, queryComponents []*domain.QueryComponent) bool { | ||
610 | + logs := selectsEditLog(ctx, querySet, queryComponents) | ||
611 | + if len(logs) > 0 { | ||
612 | + return true | ||
613 | + } | ||
614 | + logs = conditionsEditLog(ctx, querySet, queryComponents) | ||
615 | + if len(logs) > 0 { | ||
616 | + return true | ||
617 | + } | ||
618 | + logs = aggregationEditLog(ctx, querySet, queryComponents) | ||
619 | + if len(logs) > 0 { | ||
620 | + return true | ||
621 | + } | ||
622 | + for _, item := range queryComponents { | ||
623 | + if len(item.Id) == 0 { | ||
624 | + return true | ||
625 | + } | ||
626 | + } | ||
627 | + return false | ||
628 | +} | ||
629 | + | ||
630 | +// CreateOrUpdateQuerySetTable 计算集 | ||
631 | +func (ptr *QuerySetService) CreateOrUpdateQuerySetTable(ctx *domain.Context, querySet *domain.QuerySet, masterTable *domain.QueryComponentTable, queryComponents []*domain.QueryComponent) (*domain.Table, error) { | ||
455 | var ( | 632 | var ( |
456 | err error | 633 | err error |
457 | foundMasterTable *domain.Table | 634 | foundMasterTable *domain.Table |
@@ -487,6 +664,80 @@ func (ptr *QuerySetService) CreateOrUpdateQuerySetTable(ctx *domain.Context, que | @@ -487,6 +664,80 @@ func (ptr *QuerySetService) CreateOrUpdateQuerySetTable(ctx *domain.Context, que | ||
487 | return table, nil | 664 | return table, nil |
488 | } | 665 | } |
489 | 666 | ||
667 | +// CreateOrUpdateCalculateItemTable 计算项 | ||
668 | +func (ptr *QuerySetService) CreateOrUpdateCalculateItemTable(ctx *domain.Context, querySet *domain.QuerySet, masterTable *domain.QueryComponentTable, queryComponents []*domain.QueryComponent) (*domain.Table, error) { | ||
669 | + var ( | ||
670 | + err error | ||
671 | + ) | ||
672 | + dependencyTables := querySet.GetDependencyTables(queryComponents) | ||
673 | + tableRepository, _ := repository.NewTableRepository(ptr.transactionContext) | ||
674 | + queryComponent := queryComponents[0] | ||
675 | + field := DataField(querySet.Name, domain.String.ToString(), domain.MainTableField, 1) | ||
676 | + if len(queryComponent.Formula.TableFields) > 0 { | ||
677 | + field.SQLType = queryComponent.Formula.TableFields[0].FieldSQLType | ||
678 | + } | ||
679 | + var table *domain.Table = NewCopyTable(domain.TableType(querySet.Type), querySet.Name, []*domain.Field{field}, 1).WithContext(ctx).WithPrefix(strings.ToLower(querySet.Type)) | ||
680 | + table.PK = nil | ||
681 | + if querySet.QuerySetInfo.BindTableId > 0 { | ||
682 | + table, err = tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableId": querySet.QuerySetInfo.BindTableId}) | ||
683 | + if err != nil { | ||
684 | + return nil, err | ||
685 | + } | ||
686 | + table.DataFields = []*domain.Field{field} | ||
687 | + table.UpdatedAt = time.Now() | ||
688 | + } | ||
689 | + | ||
690 | + table.TableInfo.ApplyOnModule = domain.ModuleAll | ||
691 | + table.TableInfo.DependencyTables = dependencyTables | ||
692 | + table, err = tableRepository.Save(table) | ||
693 | + if err != nil { | ||
694 | + return nil, err | ||
695 | + } | ||
696 | + return table, nil | ||
697 | +} | ||
698 | + | ||
699 | +// CreateOrUpdateCalculateTable 计算表 | ||
700 | +func (ptr *QuerySetService) CreateOrUpdateCalculateTable(ctx *domain.Context, querySet *domain.QuerySet, masterTable *domain.QueryComponentTable, queryComponents []*domain.QueryComponent) (*domain.Table, error) { | ||
701 | + var ( | ||
702 | + err error | ||
703 | + foundMasterTable *domain.Table | ||
704 | + ) | ||
705 | + dependencyTables := querySet.GetDependencyTables(queryComponents) | ||
706 | + tableRepository, _ := repository.NewTableRepository(ptr.transactionContext) | ||
707 | + foundMasterTable, err = tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableId": masterTable.TableId}) | ||
708 | + if err != nil { | ||
709 | + return nil, err | ||
710 | + } | ||
711 | + masterTable = domain.NewQueryComponentTable(foundMasterTable) | ||
712 | + queryComponent := queryComponents[0] | ||
713 | + queryComponent.MasterTable = masterTable | ||
714 | + fields := make([]*domain.Field, 0) | ||
715 | + aggregationFields := queryComponent.Aggregation.AggregationFields() | ||
716 | + selectedFields := make([]string, 0) | ||
717 | + for index, f := range aggregationFields { | ||
718 | + fields = append(fields, DataField(f.DisplayName, f.Field.SQLType, domain.MainTableField, index)) | ||
719 | + selectedFields = append(selectedFields, f.Field.Name) | ||
720 | + } | ||
721 | + queryComponent.Aggregation.SelectFields = selectedFields | ||
722 | + var table *domain.Table = NewCopyTable(domain.TableType(querySet.Type), querySet.Name, fields, 0).WithContext(ctx).WithPrefix(strings.ToLower(querySet.Type)) | ||
723 | + if querySet.QuerySetInfo.BindTableId > 0 { | ||
724 | + table, err = tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableId": querySet.QuerySetInfo.BindTableId}) | ||
725 | + if err != nil { | ||
726 | + return nil, err | ||
727 | + } | ||
728 | + table.DataFields = fields | ||
729 | + table.UpdatedAt = time.Now() | ||
730 | + } | ||
731 | + | ||
732 | + table.TableInfo.ApplyOnModule = domain.ModuleAll | ||
733 | + table.TableInfo.DependencyTables = dependencyTables | ||
734 | + table, err = tableRepository.Save(table) | ||
735 | + if err != nil { | ||
736 | + return nil, err | ||
737 | + } | ||
738 | + return table, nil | ||
739 | +} | ||
740 | + | ||
490 | func (ptr *QuerySetService) Rename(ctx *domain.Context, querySetId int, name string) error { | 741 | func (ptr *QuerySetService) Rename(ctx *domain.Context, querySetId int, name string) error { |
491 | querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) | 742 | querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) |
492 | qs, err := querySetRepository.FindOne(map[string]interface{}{"querySetId": querySetId}) | 743 | qs, err := querySetRepository.FindOne(map[string]interface{}{"querySetId": querySetId}) |
@@ -520,6 +771,7 @@ func (ptr *QuerySetService) Rename(ctx *domain.Context, querySetId int, name str | @@ -520,6 +771,7 @@ func (ptr *QuerySetService) Rename(ctx *domain.Context, querySetId int, name str | ||
520 | // 日志 | 771 | // 日志 |
521 | if err = FastLog(ptr.transactionContext, domain.QuerySetLog, qs.QuerySetId, &RenameQuerySetLog{ | 772 | if err = FastLog(ptr.transactionContext, domain.QuerySetLog, qs.QuerySetId, &RenameQuerySetLog{ |
522 | LogEntry: domain.NewLogEntry(qs.Name, qs.Type, domain.UnKnown, ctx), | 773 | LogEntry: domain.NewLogEntry(qs.Name, qs.Type, domain.UnKnown, ctx), |
774 | + Qs: qs, | ||
523 | NewName: name, | 775 | NewName: name, |
524 | OldName: oldName, | 776 | OldName: oldName, |
525 | }); err != nil { | 777 | }); err != nil { |
@@ -537,7 +789,7 @@ func (ptr *QuerySetService) ChangeStatus(ctx *domain.Context, querySetId int, st | @@ -537,7 +789,7 @@ func (ptr *QuerySetService) ChangeStatus(ctx *domain.Context, querySetId int, st | ||
537 | if qs.Status == status { | 789 | if qs.Status == status { |
538 | return nil | 790 | return nil |
539 | } | 791 | } |
540 | - if qs.Type != domain.SchemaTable.ToString() { | 792 | + if !domain.TableType(qs.Type).TableStatusEditable() { |
541 | return fmt.Errorf("方案才可以修改状态") | 793 | return fmt.Errorf("方案才可以修改状态") |
542 | } | 794 | } |
543 | qs.Status = status | 795 | qs.Status = status |
@@ -593,7 +845,6 @@ func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string, | @@ -593,7 +845,6 @@ func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string, | ||
593 | return nil, err | 845 | return nil, err |
594 | } | 846 | } |
595 | copyTable := NewCopyTable(domain.TableType(t), name, table.Fields(false), 0).WithContext(ctx).WithPrefix(qs.Type) | 847 | copyTable := NewCopyTable(domain.TableType(t), name, table.Fields(false), 0).WithContext(ctx).WithPrefix(qs.Type) |
596 | - | ||
597 | copyTable, err = tableRepository.Save(copyTable) | 848 | copyTable, err = tableRepository.Save(copyTable) |
598 | if err != nil { | 849 | if err != nil { |
599 | return nil, err | 850 | return nil, err |
@@ -609,12 +860,12 @@ func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string, | @@ -609,12 +860,12 @@ func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string, | ||
609 | return nil, err | 860 | return nil, err |
610 | } | 861 | } |
611 | if len(formulasGenerateResponse.FormulaName) > 0 && formulasGenerateResponse.FormulaName != table.SQLName { | 862 | if len(formulasGenerateResponse.FormulaName) > 0 && formulasGenerateResponse.FormulaName != table.SQLName { |
612 | - copyTable.SQLName = formulasGenerateResponse.FormulaName | ||
613 | - tableRepository, _ := repository.NewTableRepository(ptr.transactionContext) | ||
614 | - copyTable, err = tableRepository.Save(copyTable) | ||
615 | - if err != nil { | ||
616 | - return nil, err | ||
617 | - } | 863 | + //copyTable.SQLName = formulasGenerateResponse.FormulaName |
864 | + //tableRepository, _ := repository.NewTableRepository(ptr.transactionContext) | ||
865 | + //copyTable, err = tableRepository.Save(copyTable) | ||
866 | + //if err != nil { | ||
867 | + // return nil, err | ||
868 | + //} | ||
618 | } | 869 | } |
619 | copy.QuerySetInfo.BindTableId = copyTable.TableId | 870 | copy.QuerySetInfo.BindTableId = copyTable.TableId |
620 | } | 871 | } |
@@ -622,6 +873,14 @@ func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string, | @@ -622,6 +873,14 @@ func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string, | ||
622 | if err != nil { | 873 | if err != nil { |
623 | return nil, err | 874 | return nil, err |
624 | } | 875 | } |
876 | + // 日志 | ||
877 | + if err = FastLog(ptr.transactionContext, domain.QuerySetLog, qs.QuerySetId, &CopyQuerySetLog{ | ||
878 | + LogEntry: domain.NewLogEntry(qs.Name, qs.Type, domain.UnKnown, ctx), | ||
879 | + From: qs, | ||
880 | + To: copy, | ||
881 | + }); err != nil { | ||
882 | + return nil, err | ||
883 | + } | ||
625 | return copy, nil | 884 | return copy, nil |
626 | } | 885 | } |
627 | 886 | ||
@@ -649,22 +908,30 @@ func (ptr *QuerySetService) Delete(ctx *domain.Context, querySetId int) error { | @@ -649,22 +908,30 @@ func (ptr *QuerySetService) Delete(ctx *domain.Context, querySetId int) error { | ||
649 | return err | 908 | return err |
650 | } | 909 | } |
651 | querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) | 910 | querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext) |
911 | + tableRepository, _ := repository.NewTableRepository(ptr.transactionContext) | ||
652 | tableDependencyService, _ := NewTableDependencyService(ptr.transactionContext) | 912 | tableDependencyService, _ := NewTableDependencyService(ptr.transactionContext) |
653 | // 1.判断依赖,删除表 | 913 | // 1.判断依赖,删除表 |
654 | for i := range querySets { | 914 | for i := range querySets { |
655 | if _, err := querySetRepository.Remove(querySets[i]); err != nil { | 915 | if _, err := querySetRepository.Remove(querySets[i]); err != nil { |
656 | return err | 916 | return err |
657 | } | 917 | } |
658 | - if querySets[i].Flag != domain.FlagGroup && querySets[i].Type == domain.SchemaTable.ToString() && querySets[i].Status == domain.StatusOn { | 918 | + if querySets[i].Flag != domain.FlagGroup && |
919 | + domain.TableType(querySets[i].Type).TableStatusEditable() && | ||
920 | + querySets[i].Status == domain.StatusOn { | ||
659 | return ErrQuerySetDeleteStatusOn | 921 | return ErrQuerySetDeleteStatusOn |
660 | } | 922 | } |
661 | - if querySets[i].QuerySetInfo.BindTableId > 0 { | ||
662 | - if err := tableDependencyService.HasDependencyError(ctx, querySets[i].QuerySetInfo.BindTableId); err != nil { | 923 | + tableId := querySets[i].QuerySetInfo.BindTableId |
924 | + if tableId > 0 { | ||
925 | + if err := tableDependencyService.HasDependencyError(ctx, tableId); err != nil { | ||
663 | return err | 926 | return err |
664 | } | 927 | } |
665 | - if err := dao.TableSoftDelete(ptr.transactionContext, querySets[i].QuerySetInfo.BindTableId, domain.TableType(querySets[i].Type)); err != nil { | 928 | + t, _ := tableRepository.FindOne(map[string]interface{}{"tableId": tableId}) |
929 | + if t != nil { | ||
930 | + if err := dao.TableSoftDelete(ptr.transactionContext, tableId, domain.TableType(querySets[i].Type)); err != nil { | ||
666 | return err | 931 | return err |
667 | } | 932 | } |
933 | + starrocks.DropView(starrocks.DB, t.SQLName) | ||
934 | + } | ||
668 | } | 935 | } |
669 | } | 936 | } |
670 | // 2.底层清理 | 937 | // 2.底层清理 |
@@ -25,6 +25,8 @@ type Table struct { | @@ -25,6 +25,8 @@ type Table struct { | ||
25 | DataFields []*domain.Field `comment:"数据列"` | 25 | DataFields []*domain.Field `comment:"数据列"` |
26 | // 手动添加的列 | 26 | // 手动添加的列 |
27 | ManualFields []*domain.Field `comment:"手动添加的列"` | 27 | ManualFields []*domain.Field `comment:"手动添加的列"` |
28 | + // 默认排序列 | ||
29 | + //OrderFields []*domain.Field `comment:"默认排序列"` | ||
28 | // 创建时间 | 30 | // 创建时间 |
29 | CreatedAt time.Time `comment:"创建时间"` | 31 | CreatedAt time.Time `comment:"创建时间"` |
30 | // 更新时间 | 32 | // 更新时间 |
@@ -161,6 +161,9 @@ func (repository *QuerySetRepository) Find(queryOptions map[string]interface{}) | @@ -161,6 +161,9 @@ func (repository *QuerySetRepository) Find(queryOptions map[string]interface{}) | ||
161 | query.SetWhereByQueryOption("flag = ?", "flag") | 161 | query.SetWhereByQueryOption("flag = ?", "flag") |
162 | query.SetWhereByQueryOption("status = ?", "status") | 162 | query.SetWhereByQueryOption("status = ?", "status") |
163 | query.SetWhereByQueryOption(fmt.Sprintf("name like '%%%v%%'", queryOptions["matchName"]), "matchName") | 163 | query.SetWhereByQueryOption(fmt.Sprintf("name like '%%%v%%'", queryOptions["matchName"]), "matchName") |
164 | + if v, ok := queryOptions["types"]; ok && len(v.([]string)) > 0 { | ||
165 | + query.Where("type in (?)", pg.In(v)) | ||
166 | + } | ||
164 | if v, ok := queryOptions["inParentIds"]; ok && len(v.([]int)) > 0 { | 167 | if v, ok := queryOptions["inParentIds"]; ok && len(v.([]int)) > 0 { |
165 | query.Where("parent_id in (?)", pg.In(v)) | 168 | query.Where("parent_id in (?)", pg.In(v)) |
166 | } | 169 | } |
@@ -167,7 +167,7 @@ func (repository *TableRepository) Find(queryOptions map[string]interface{}) (in | @@ -167,7 +167,7 @@ func (repository *TableRepository) Find(queryOptions map[string]interface{}) (in | ||
167 | query := sqlbuilder.BuildQuery(tx.Model(&tableModels), queryOptions) | 167 | query := sqlbuilder.BuildQuery(tx.Model(&tableModels), queryOptions) |
168 | WhereContext(query, queryOptions) | 168 | WhereContext(query, queryOptions) |
169 | query.SetWhereByQueryOption(fmt.Sprintf("name like '%%%v%%'", queryOptions["name"]), "name") | 169 | query.SetWhereByQueryOption(fmt.Sprintf("name like '%%%v%%'", queryOptions["name"]), "name") |
170 | - | 170 | + query.SetWhereByQueryOption("table_id = ?", "tableId") |
171 | query.SetWhereByQueryOption("parent_id = ?", "parentId") | 171 | query.SetWhereByQueryOption("parent_id = ?", "parentId") |
172 | if v, ok := queryOptions["tableIds"]; ok && len(v.([]int)) > 0 { | 172 | if v, ok := queryOptions["tableIds"]; ok && len(v.([]int)) > 0 { |
173 | query.Where(`table_id in (?)`, pg.In(v.([]int))) | 173 | query.Where(`table_id in (?)`, pg.In(v.([]int))) |
1 | package starrocks | 1 | package starrocks |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "bytes" | ||
4 | "fmt" | 5 | "fmt" |
5 | "github.com/google/uuid" | 6 | "github.com/google/uuid" |
6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
7 | "gorm.io/gorm" | 8 | "gorm.io/gorm" |
9 | + "html" | ||
10 | + "html/template" | ||
8 | ) | 11 | ) |
9 | 12 | ||
10 | func Insert(db *gorm.DB, tableName string, fields []*domain.FieldValue) error { | 13 | func Insert(db *gorm.DB, tableName string, fields []*domain.FieldValue) error { |
@@ -72,3 +75,36 @@ func DropView(db *gorm.DB, tableName string) error { | @@ -72,3 +75,36 @@ func DropView(db *gorm.DB, tableName string) error { | ||
72 | tx := db.Exec("DROP VIEW IF EXISTS " + tableName) | 75 | tx := db.Exec("DROP VIEW IF EXISTS " + tableName) |
73 | return tx.Error | 76 | return tx.Error |
74 | } | 77 | } |
78 | + | ||
79 | +func Exec(db *gorm.DB, sql string) error { | ||
80 | + tx := db.Exec(sql) | ||
81 | + return tx.Error | ||
82 | +} | ||
83 | + | ||
84 | +func CreateViewSql(viewName string, fields []*domain.Field, selectSql string) string { | ||
85 | + sql := ` | ||
86 | +DROP VIEW IF EXISTS {{.ViewName}}; | ||
87 | +create view {{.ViewName}}( | ||
88 | +{{.Field}} | ||
89 | +) as( | ||
90 | +{{.Sql}} | ||
91 | +) | ||
92 | +` | ||
93 | + tmp := template.New("ViewCreator") | ||
94 | + tmp.Parse(sql) | ||
95 | + | ||
96 | + buf := bytes.NewBuffer(nil) | ||
97 | + bufField := bytes.NewBuffer(nil) | ||
98 | + for i, f := range fields { | ||
99 | + bufField.WriteString(fmt.Sprintf(`%s COMMENT "%v"`, f.SQLName, f.Name)) | ||
100 | + if i != len(fields)-1 { | ||
101 | + bufField.WriteString(",\n") | ||
102 | + } | ||
103 | + } | ||
104 | + tmp.Execute(buf, map[string]interface{}{ | ||
105 | + "ViewName": viewName, | ||
106 | + "Field": bufField.String(), | ||
107 | + "Sql": selectSql, | ||
108 | + }) | ||
109 | + return html.UnescapeString(buf.String()) | ||
110 | +} |
@@ -3,6 +3,7 @@ package starrocks | @@ -3,6 +3,7 @@ package starrocks | ||
3 | import ( | 3 | import ( |
4 | "database/sql" | 4 | "database/sql" |
5 | "fmt" | 5 | "fmt" |
6 | + "github.com/zeromicro/go-zero/core/collection" | ||
6 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | 7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" |
7 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" | 8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils" |
8 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" | 9 | "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log" |
@@ -66,6 +67,15 @@ func (o *QueryOptions) SetDefaultOrder() *QueryOptions { | @@ -66,6 +67,15 @@ func (o *QueryOptions) SetDefaultOrder() *QueryOptions { | ||
66 | // 没有排序的加一个排序,才能分页 | 67 | // 没有排序的加一个排序,才能分页 |
67 | if !hasOrder { | 68 | if !hasOrder { |
68 | if o.Table != nil { | 69 | if o.Table != nil { |
70 | + if o.Table.PK == nil { | ||
71 | + //o.Where = append(o.Where, Condition{ | ||
72 | + // Condition: domain.Condition{ | ||
73 | + // Field: o.Table.DataFields[0], | ||
74 | + // Order: "ASC", | ||
75 | + // }, | ||
76 | + //}) | ||
77 | + return o | ||
78 | + } | ||
69 | o.Where = append(o.Where, Condition{ | 79 | o.Where = append(o.Where, Condition{ |
70 | Condition: domain.Condition{ | 80 | Condition: domain.Condition{ |
71 | Field: o.Table.PK, | 81 | Field: o.Table.PK, |
@@ -105,6 +115,14 @@ func (o *QueryOptions) AdditionOptionsByTable(table *domain.Table) *QueryOptions | @@ -105,6 +115,14 @@ func (o *QueryOptions) AdditionOptionsByTable(table *domain.Table) *QueryOptions | ||
105 | }, | 115 | }, |
106 | In: []interface{}{domain.QuerySetLog.ToString()}, | 116 | In: []interface{}{domain.QuerySetLog.ToString()}, |
107 | }}) | 117 | }}) |
118 | + case domain.DBTableFormulaLog.ToInt(): | ||
119 | + o.SetCondition([]domain.Condition{{ | ||
120 | + Field: &domain.Field{ | ||
121 | + SQLName: "log_type", | ||
122 | + SQLType: domain.String.ToString(), | ||
123 | + }, | ||
124 | + In: []interface{}{domain.FormulaLog.ToString()}, | ||
125 | + }}) | ||
108 | } | 126 | } |
109 | return o | 127 | return o |
110 | } | 128 | } |
@@ -280,7 +298,7 @@ func queryWithoutLimitOffset(query *gorm.DB, params QueryOptions) { | @@ -280,7 +298,7 @@ func queryWithoutLimitOffset(query *gorm.DB, params QueryOptions) { | ||
280 | } | 298 | } |
281 | if len(params.Where) > 0 { | 299 | if len(params.Where) > 0 { |
282 | for _, w := range params.Where { | 300 | for _, w := range params.Where { |
283 | - if w.Field.Flag == domain.ManualField { | 301 | + if w.Field != nil && w.Field.Flag == domain.ManualField { |
284 | continue | 302 | continue |
285 | } | 303 | } |
286 | w.SetWhere(params, query) | 304 | w.SetWhere(params, query) |
@@ -386,3 +404,66 @@ func WrapQueryHasDuplicateRowBySql(sql string, db *gorm.DB) func() (int64, int64 | @@ -386,3 +404,66 @@ func WrapQueryHasDuplicateRowBySql(sql string, db *gorm.DB) func() (int64, int64 | ||
386 | return total, duplicateTotal, nil | 404 | return total, duplicateTotal, nil |
387 | } | 405 | } |
388 | } | 406 | } |
407 | + | ||
408 | +func WrapQueryHasDuplicateRowBySqlParam1(sql string, db *gorm.DB, result1 interface{}) error { | ||
409 | + query := db.Raw(sql) | ||
410 | + row := query.Row() | ||
411 | + if row.Err() != nil { | ||
412 | + return row.Err() | ||
413 | + } | ||
414 | + if err := row.Scan(result1); err != nil { | ||
415 | + return err | ||
416 | + } | ||
417 | + return nil | ||
418 | +} | ||
419 | + | ||
420 | +func CalculateItemValue(db *gorm.DB, fieldExpr *domain.FieldExpr) string { | ||
421 | + var value string | ||
422 | + sql := CalculateItemViewSql(fieldExpr) | ||
423 | + WrapQueryHasDuplicateRowBySqlParam1(sql, db, &value) | ||
424 | + return value | ||
425 | +} | ||
426 | + | ||
427 | +func CalculateItemViewSql(fieldExpr *domain.FieldExpr) string { | ||
428 | + sql := "select " + fieldExpr.ExprSql | ||
429 | + tables := collection.NewSet() | ||
430 | + for _, f := range fieldExpr.TableFields { | ||
431 | + if len(f.TableSqlName) == 0 { | ||
432 | + continue | ||
433 | + } | ||
434 | + tables.AddStr(f.TableSqlName) | ||
435 | + } | ||
436 | + if len(tables.KeysStr()) > 0 { | ||
437 | + sql += fmt.Sprintf(" from %v", strings.Join(tables.KeysStr(), ",")) | ||
438 | + } | ||
439 | + return sql | ||
440 | +} | ||
441 | + | ||
442 | +func CalculateTableViewSql(table string, aggregation *domain.Aggregation) string { | ||
443 | + | ||
444 | + columns := make([]string, 0) | ||
445 | + groups := make([]string, 0) | ||
446 | + orders := make([]string, 0) | ||
447 | + for _, f := range aggregation.RowFields { | ||
448 | + columns = append(columns, f.Expr.ExprSql) | ||
449 | + if f.Order != "" { | ||
450 | + orders = append(orders, fmt.Sprintf("%v %v", f.Field.SQLName, f.Order)) | ||
451 | + } | ||
452 | + groups = append(groups, f.Field.SQLName) | ||
453 | + } | ||
454 | + for _, f := range aggregation.ValueFields { | ||
455 | + columns = append(columns, f.Expr.ExprSql) | ||
456 | + if f.Order != "" { | ||
457 | + orders = append(orders, fmt.Sprintf("%v %v", f.Field.SQLName, f.Order)) | ||
458 | + } | ||
459 | + } | ||
460 | + sql := "select " + strings.Join(columns, ",") | ||
461 | + sql += fmt.Sprintf("\nfrom %v", table) | ||
462 | + if len(groups) > 0 { | ||
463 | + sql += "\ngroup by " + strings.Join(groups, ",") | ||
464 | + } | ||
465 | + if len(orders) > 0 { | ||
466 | + sql += "\norder by " + strings.Join(orders, ",") | ||
467 | + } | ||
468 | + return sql | ||
469 | +} |
@@ -16,7 +16,7 @@ import ( | @@ -16,7 +16,7 @@ import ( | ||
16 | func init() { | 16 | func init() { |
17 | web.BConfig.AppName = "character-library-metadata-bastion" | 17 | web.BConfig.AppName = "character-library-metadata-bastion" |
18 | web.BConfig.CopyRequestBody = true | 18 | web.BConfig.CopyRequestBody = true |
19 | - web.BConfig.RunMode = "dev" | 19 | + web.BConfig.RunMode = "dev" //"prod" |
20 | web.BConfig.Listen.HTTPPort = 8080 | 20 | web.BConfig.Listen.HTTPPort = 8080 |
21 | web.BConfig.Listen.EnableAdmin = false | 21 | web.BConfig.Listen.EnableAdmin = false |
22 | web.BConfig.WebConfig.CommentRouterPath = "/pkg/port/beego/routers" | 22 | web.BConfig.WebConfig.CommentRouterPath = "/pkg/port/beego/routers" |
@@ -37,6 +37,22 @@ func (controller *QuerySetController) PreviewPrepare() { | @@ -37,6 +37,22 @@ func (controller *QuerySetController) PreviewPrepare() { | ||
37 | controller.Response(data, err) | 37 | controller.Response(data, err) |
38 | } | 38 | } |
39 | 39 | ||
40 | +func (controller *QuerySetController) CalculateItemPreview() { | ||
41 | + querySetService := service.NewQuerySetService(nil) | ||
42 | + updateQuerySetCommand := &query.CalculateItemPreviewQuery{} | ||
43 | + Must(controller.Unmarshal(updateQuerySetCommand)) | ||
44 | + data, err := querySetService.CalculateItemPreview(ParseContext(controller.BaseController), updateQuerySetCommand) | ||
45 | + controller.Response(data, err) | ||
46 | +} | ||
47 | + | ||
48 | +func (controller *QuerySetController) CalculateItemExport() { | ||
49 | + querySetService := service.NewQuerySetService(nil) | ||
50 | + updateQuerySetCommand := &query.CalculateItemPreviewQuery{} | ||
51 | + Must(controller.Unmarshal(updateQuerySetCommand)) | ||
52 | + data, err := querySetService.CalculateItemExport(ParseContext(controller.BaseController), updateQuerySetCommand) | ||
53 | + controller.Response(data, err) | ||
54 | +} | ||
55 | + | ||
40 | func (controller *QuerySetController) GetQuerySet() { | 56 | func (controller *QuerySetController) GetQuerySet() { |
41 | querySetService := service.NewQuerySetService(nil) | 57 | querySetService := service.NewQuerySetService(nil) |
42 | getQuerySetQuery := &query.GetQuerySetQuery{} | 58 | getQuerySetQuery := &query.GetQuerySetQuery{} |
@@ -107,7 +107,7 @@ func (controller *TableController) Search() { | @@ -107,7 +107,7 @@ func (controller *TableController) Search() { | ||
107 | 107 | ||
108 | func (controller *TableController) RelationGraph() { | 108 | func (controller *TableController) RelationGraph() { |
109 | tableService := service.NewTableService(nil) | 109 | tableService := service.NewTableService(nil) |
110 | - cmd := &query.SearchTableQuery{} | 110 | + cmd := &query.SearchTableRelationGraphQuery{} |
111 | Must(controller.Unmarshal(cmd)) | 111 | Must(controller.Unmarshal(cmd)) |
112 | cmd.TableTypes = []string{domain.MainTable.ToString(), domain.SideTable.ToString(), domain.SubTable.ToString()} | 112 | cmd.TableTypes = []string{domain.MainTable.ToString(), domain.SideTable.ToString(), domain.SubTable.ToString()} |
113 | cmd.Context = ParseContext(controller.BaseController) | 113 | cmd.Context = ParseContext(controller.BaseController) |
@@ -149,6 +149,15 @@ func (controller *TableController) SearchQuerySetTables() { | @@ -149,6 +149,15 @@ func (controller *TableController) SearchQuerySetTables() { | ||
149 | controller.Response(data, err) | 149 | controller.Response(data, err) |
150 | } | 150 | } |
151 | 151 | ||
152 | +func (controller *TableController) TableObjectSearch() { | ||
153 | + tableService := service.NewTableService(nil) | ||
154 | + cmd := &query.SearchTableQuery{} | ||
155 | + Must(controller.Unmarshal(cmd)) | ||
156 | + cmd.Context = ParseContext(controller.BaseController) | ||
157 | + data, err := tableService.TableObjectSearch(cmd) | ||
158 | + controller.Response(data, err) | ||
159 | +} | ||
160 | + | ||
152 | func (controller *TableController) UpdateTableStruct() { | 161 | func (controller *TableController) UpdateTableStruct() { |
153 | tableService := service.NewTableService(nil) | 162 | tableService := service.NewTableService(nil) |
154 | cmd := &command.UpdateTableStructCommand{} | 163 | cmd := &command.UpdateTableStructCommand{} |
@@ -19,4 +19,19 @@ func init() { | @@ -19,4 +19,19 @@ func init() { | ||
19 | web.Router("/data/query-sets/rename", &controllers.QuerySetController{}, "Post:Rename") | 19 | web.Router("/data/query-sets/rename", &controllers.QuerySetController{}, "Post:Rename") |
20 | web.Router("/data/query-sets/search", &controllers.QuerySetController{}, "Post:SearchQuerySet") | 20 | web.Router("/data/query-sets/search", &controllers.QuerySetController{}, "Post:SearchQuerySet") |
21 | web.Router("/data/query-sets/preview-prepare", &controllers.QuerySetController{}, "Post:PreviewPrepare") | 21 | web.Router("/data/query-sets/preview-prepare", &controllers.QuerySetController{}, "Post:PreviewPrepare") |
22 | + | ||
23 | + web.Router("/data/query-sets/formula/", &controllers.QuerySetController{}, "Post:CreateQuerySet") | ||
24 | + web.Router("/data/query-sets/formula/:querySetId", &controllers.QuerySetController{}, "Put:UpdateQuerySet") | ||
25 | + web.Router("/data/query-sets/formula/:querySetId", &controllers.QuerySetController{}, "Get:GetQuerySet") | ||
26 | + web.Router("/data/query-sets/formula/:querySetId", &controllers.QuerySetController{}, "Delete:RemoveQuerySet") | ||
27 | + | ||
28 | + web.Router("/data/query-sets/formula/change-status", &controllers.QuerySetController{}, "Post:ChangeStatus") | ||
29 | + web.Router("/data/query-sets/formula/copy", &controllers.QuerySetController{}, "Post:Copy") | ||
30 | + web.Router("/data/query-sets/formula/move", &controllers.QuerySetController{}, "Post:Move") | ||
31 | + web.Router("/data/query-sets/formula/rename", &controllers.QuerySetController{}, "Post:Rename") | ||
32 | + web.Router("/data/query-sets/formula/search", &controllers.QuerySetController{}, "Post:SearchQuerySet") | ||
33 | + web.Router("/data/query-sets/formula/calculate-table-preview-prepare", &controllers.QuerySetController{}, "Post:PreviewPrepare") | ||
34 | + | ||
35 | + web.Router("/data/query-sets/formula/calculate-item-preview", &controllers.QuerySetController{}, "Post:CalculateItemPreview") | ||
36 | + web.Router("/data/query-sets/formula/calculate-item-export", &controllers.QuerySetController{}, "Post:CalculateItemExport") | ||
22 | } | 37 | } |
@@ -33,8 +33,9 @@ func init() { | @@ -33,8 +33,9 @@ func init() { | ||
33 | web.Router("/data/tables/row-edit", &controllers.TableController{}, "Post:RowEdit") | 33 | web.Router("/data/tables/row-edit", &controllers.TableController{}, "Post:RowEdit") |
34 | 34 | ||
35 | web.Router("/data/field-optional-values", &controllers.TableController{}, "Post:FieldOptionalValues") | 35 | web.Router("/data/field-optional-values", &controllers.TableController{}, "Post:FieldOptionalValues") |
36 | + web.Router("/data/table-object-search", &controllers.TableController{}, "Post:TableObjectSearch") | ||
36 | 37 | ||
37 | web.Router("/business/db-table-preview", &controllers.TableController{}, "Post:DBTablePreview") | 38 | web.Router("/business/db-table-preview", &controllers.TableController{}, "Post:DBTablePreview") |
38 | - | ||
39 | web.Router("/data/table-preview", &controllers.TableController{}, "Post:Preview") | 39 | web.Router("/data/table-preview", &controllers.TableController{}, "Post:Preview") |
40 | + | ||
40 | } | 41 | } |
-
请 注册 或 登录 后发表评论