作者 yangfu

feat: view table by type

@@ -2,10 +2,11 @@ package command @@ -2,10 +2,11 @@ package command
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 - "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"  
6 "reflect" 5 "reflect"
7 "strings" 6 "strings"
8 7
  8 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  9 +
9 "github.com/beego/beego/v2/core/validation" 10 "github.com/beego/beego/v2/core/validation"
10 ) 11 )
11 12
@@ -16,6 +17,7 @@ type FieldOptionalValuesCommand struct { @@ -16,6 +17,7 @@ type FieldOptionalValuesCommand struct {
16 Match string `cname:"匹配内容" json:"match"` 17 Match string `cname:"匹配内容" json:"match"`
17 PageNumber int `json:"pageNumber"` 18 PageNumber int `json:"pageNumber"`
18 PageSize int `json:"pageSize"` 19 PageSize int `json:"pageSize"`
  20 + Condition *domain.Condition `json:"condition"`
19 } 21 }
20 22
21 func (cmd *FieldOptionalValuesCommand) Valid(validation *validation.Validation) { 23 func (cmd *FieldOptionalValuesCommand) Valid(validation *validation.Validation) {
@@ -23,6 +23,9 @@ func (cmd *TablePreviewCommand) Valid(validation *validation.Validation) { @@ -23,6 +23,9 @@ func (cmd *TablePreviewCommand) Valid(validation *validation.Validation) {
23 cmd.Where.PageNumber = cmd.PageNumber 23 cmd.Where.PageNumber = cmd.PageNumber
24 cmd.Where.PageSize = cmd.PageSize 24 cmd.Where.PageSize = cmd.PageSize
25 } 25 }
  26 + if err := cmd.Where.ValidSql(); err != nil {
  27 + validation.Error(err.Error())
  28 + }
26 } 29 }
27 30
28 func (cmd *TablePreviewCommand) ValidateCommand() error { 31 func (cmd *TablePreviewCommand) ValidateCommand() error {
@@ -24,6 +24,9 @@ func (cmd *DBTablePreviewCommand) Valid(validation *validation.Validation) { @@ -24,6 +24,9 @@ func (cmd *DBTablePreviewCommand) Valid(validation *validation.Validation) {
24 cmd.Where.PageNumber = cmd.PageNumber 24 cmd.Where.PageNumber = cmd.PageNumber
25 cmd.Where.PageSize = cmd.PageSize 25 cmd.Where.PageSize = cmd.PageSize
26 } 26 }
  27 + if err := cmd.Where.ValidSql(); err != nil {
  28 + validation.Error(err.Error())
  29 + }
27 } 30 }
28 31
29 func (cmd *DBTablePreviewCommand) ValidateCommand() error { 32 func (cmd *DBTablePreviewCommand) ValidateCommand() error {
1 package dto 1 package dto
2 2
3 -import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" 3 +import (
  4 + "strings"
  5 +
  6 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
  7 +)
4 8
5 type TableDto struct { 9 type TableDto struct {
6 // 表Id 10 // 表Id
@@ -19,3 +23,38 @@ func (d *TableDto) Load(m *domain.Table) { @@ -19,3 +23,38 @@ func (d *TableDto) Load(m *domain.Table) {
19 d.Name = m.Name 23 d.Name = m.Name
20 d.ParentId = m.ParentId 24 d.ParentId = m.ParentId
21 } 25 }
  26 +
  27 +func SuitTableByView(tables []*TableDto, view string, name string) []*TableDto {
  28 + var mainTables = make(map[int]*TableDto)
  29 + var res = make([]*TableDto, 0)
  30 + if view == "main" {
  31 + for i := range tables {
  32 + t := tables[i]
  33 + if t.ParentId == 0 && t.TableType == domain.MainTable.ToString() {
  34 + mainTables[t.TableId] = t
  35 + res = append(res, t)
  36 + }
  37 + }
  38 + for i := range tables {
  39 + t := tables[i]
  40 + if t.TableType == domain.SubTable.ToString() {
  41 + if _, ok := mainTables[t.ParentId]; ok {
  42 + res = append(res, t)
  43 + }
  44 + }
  45 + }
  46 + } else {
  47 + res = tables
  48 + }
  49 + var matchName = make([]*TableDto, 0)
  50 + if len(name) > 0 {
  51 + for i := range res {
  52 + t := res[i]
  53 + if strings.Contains(t.Name, name) {
  54 + matchName = append(matchName, t)
  55 + }
  56 + }
  57 + res = matchName
  58 + }
  59 + return res
  60 +}
@@ -12,6 +12,7 @@ import ( @@ -12,6 +12,7 @@ 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 // 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表 16 // 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表
16 TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes"` 17 TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes"`
17 // 父级ID 18 // 父级ID
@@ -2,6 +2,7 @@ package service @@ -2,6 +2,7 @@ package service
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 +
5 "github.com/linmadan/egglib-go/core/application" 6 "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/factory"
7 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command" 8 "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command"
@@ -85,6 +86,11 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd * @@ -85,6 +86,11 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd *
85 }, 86 },
86 }, 87 },
87 } 88 }
  89 + if cmd.Condition != nil {
  90 + options.Where = append(options.Where, starrocks.Condition{
  91 + Condition: *cmd.Condition,
  92 + })
  93 + }
88 options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize) 94 options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize)
89 95
90 dataTable, err = starrocks.Query(*options, starrocks.WrapQueryFuncWithDB(db)) 96 dataTable, err = starrocks.Query(*options, starrocks.WrapQueryFuncWithDB(db))
@@ -241,6 +241,47 @@ func (tableService *TableService) Search(searchQuery *query.SearchTableQuery) (i @@ -241,6 +241,47 @@ func (tableService *TableService) Search(searchQuery *query.SearchTableQuery) (i
241 }, nil 241 }, nil
242 } 242 }
243 243
  244 +// 表搜索
  245 +func (tableService *TableService) RelationGraph(searchQuery *query.SearchTableQuery) (interface{}, error) {
  246 + if err := searchQuery.ValidateQuery(); err != nil {
  247 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  248 + }
  249 + transactionContext, err := factory.CreateTransactionContext(nil)
  250 + if err != nil {
  251 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  252 + }
  253 + if err := transactionContext.StartTransaction(); err != nil {
  254 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  255 + }
  256 + defer func() {
  257 + transactionContext.RollbackTransaction()
  258 + }()
  259 +
  260 + tableRepository, _, _ := factory.FastPgTable(transactionContext, 0)
  261 + name :=searchQuery.Name
  262 + searchQuery.Name = ""
  263 + _, tables, err := tableRepository.Find(utils.ObjectToMap(searchQuery))
  264 + if err != nil {
  265 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  266 + }
  267 +
  268 + var result = make([]*dto.TableDto, 0)
  269 + for _, table := range tables {
  270 + var item = &dto.TableDto{}
  271 + item.Load(table)
  272 + result = append(result, item)
  273 + }
  274 +
  275 + if err := transactionContext.CommitTransaction(); err != nil {
  276 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  277 + }
  278 + result = dto.SuitTableByView(result,searchQuery.ViewType,name)
  279 + return map[string]interface{}{
  280 + "count": len(result),
  281 + "tables":result,
  282 + }, nil
  283 +}
  284 +
244 // 更新表服务 285 // 更新表服务
245 func (tableService *TableService) UpdateTable(updateTableCommand *command.UpdateTableCommand) (interface{}, error) { 286 func (tableService *TableService) UpdateTable(updateTableCommand *command.UpdateTableCommand) (interface{}, error) {
246 if err := updateTableCommand.ValidateCommand(); err != nil { 287 if err := updateTableCommand.ValidateCommand(); err != nil {
@@ -19,6 +19,29 @@ func (w Where) Offset() int { @@ -19,6 +19,29 @@ func (w Where) Offset() int {
19 return (w.PageNumber - 1) * w.PageSize 19 return (w.PageNumber - 1) * w.PageSize
20 } 20 }
21 21
  22 +func (w Where) ValidSql() (err error) {
  23 + for _, c := range w.Conditions {
  24 + if err = SqlDetections(c.Like); err != nil {
  25 + return err
  26 + }
  27 + //if err = SqlDetections(c.In...); err != nil {
  28 + // return err
  29 + //}
  30 + //if err = SqlDetections(c.Ex...); err != nil {
  31 + // return err
  32 + //}
  33 + if err = SqlDetections(c.Order); err != nil {
  34 + return err
  35 + }
  36 + for _, r := range c.Range {
  37 + if err = SqlDetections(r.Val); err != nil {
  38 + return err
  39 + }
  40 + }
  41 + }
  42 + return
  43 +}
  44 +
22 type Condition struct { 45 type Condition struct {
23 Field *Field `json:"field"` 46 Field *Field `json:"field"`
24 Like string `json:"like"` 47 Like string `json:"like"`
  1 +package domain
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
  6 + "strings"
  7 +)
  8 +
  9 +var sqlKeys = []string{
  10 + "'",
  11 + "`",
  12 + //",",
  13 + "--",
  14 + "/*",
  15 + //";",
  16 + "(",
  17 + ")",
  18 + "#",
  19 + "*",
  20 + "or",
  21 + "=",
  22 + "having ",
  23 + "union",
  24 + "sleep",
  25 + "as ",
  26 + "from",
  27 + "where",
  28 + "exists",
  29 + "and",
  30 + "&&",
  31 + "or",
  32 + "||",
  33 + "not",
  34 + "in",
  35 + "like",
  36 + "is",
  37 + "between",
  38 + "union",
  39 + "all",
  40 + "having",
  41 + "order",
  42 + "group",
  43 + "by",
  44 + "print",
  45 + "sleep",
  46 +}
  47 +
  48 +var ErrorSqlInject = fmt.Errorf("!!! 请检查输入的内容,存在注入风险")
  49 +
  50 +func SqlDetections(args ...interface{}) error {
  51 + for _, item := range args {
  52 + if err := sqlDetection(item); err != nil {
  53 + return err
  54 + }
  55 + }
  56 + return nil
  57 +}
  58 +
  59 +func sqlDetection(val interface{}) error {
  60 + sVal := strings.ToLower(utils.AssertString(val))
  61 + for _, kw := range sqlKeys {
  62 + if strings.Contains(sVal, kw) {
  63 + return ErrorSqlInject
  64 + }
  65 + }
  66 + return nil
  67 +}
@@ -24,7 +24,8 @@ func (ptr *GenerateMainTableService) GenerateTable(ctx *domain.Context, fileId i @@ -24,7 +24,8 @@ func (ptr *GenerateMainTableService) GenerateTable(ctx *domain.Context, fileId i
24 if err != nil { 24 if err != nil {
25 return nil, fmt.Errorf("文件未校验") 25 return nil, fmt.Errorf("文件未校验")
26 } 26 }
27 - duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": tableName}) 27 + duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": tableName,
  28 + "tableTypes":[]string{string(domain.MainTable),string(domain.SubTable),string(domain.SideTable)}})
28 if err == nil && duplicateTable != nil { 29 if err == nil && duplicateTable != nil {
29 return nil, fmt.Errorf("表名称重复") 30 return nil, fmt.Errorf("表名称重复")
30 } 31 }
@@ -136,6 +136,9 @@ func (repository *TableRepository) FindOne(queryOptions map[string]interface{}) @@ -136,6 +136,9 @@ func (repository *TableRepository) FindOne(queryOptions map[string]interface{})
136 query.SetWhereByQueryOption(`table_type = ?`, "tableType") 136 query.SetWhereByQueryOption(`table_type = ?`, "tableType")
137 query.SetWhereByQueryOption("name = ?", "tableName") 137 query.SetWhereByQueryOption("name = ?", "tableName")
138 query.SetWhereByQueryOption("parent_id = ?", "parentId") 138 query.SetWhereByQueryOption("parent_id = ?", "parentId")
  139 + if v, ok := queryOptions["tableTypes"]; ok && len(v.([]string)) > 0 {
  140 + query.Where(`table_type in (?)`, pg.In(v.([]string)))
  141 + }
139 if err := query.First(); err != nil { 142 if err := query.First(); err != nil {
140 if err.Error() == "pg: no rows in result set" { 143 if err.Error() == "pg: no rows in result set" {
141 return nil, domain.ErrorNotFound 144 return nil, domain.ErrorNotFound
@@ -111,7 +111,7 @@ func (controller *TableController) RelationGraph() { @@ -111,7 +111,7 @@ func (controller *TableController) RelationGraph() {
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)
114 - data, err := tableService.Search(cmd) 114 + data, err := tableService.RelationGraph(cmd)
115 controller.Response(data, err) 115 controller.Response(data, err)
116 } 116 }
117 117