yjp 1 жил өмнө
parent
commit
36f460f939

+ 38 - 0
convenient/domain/query_rule/definition/api.go

@@ -0,0 +1,38 @@
+package definition
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/api/request"
+	"git.sxidc.com/go-framework/baize/framework/core/api/response"
+	"git.sxidc.com/go-framework/baize/framework/core/domain"
+	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
+)
+
+// Simple Bind参数
+type Simple struct {
+	// schema
+	Schema string
+}
+
+func (simple *Simple) Bind(binder *binding.Binder) {
+	binding.GetBind(binder, &binding.SimpleBindItem[map[string]any]{
+		Path:             "/queryRuleDefinition/get",
+		SendResponseFunc: response.SendMapResponse,
+		RequestParams:    &GetQueryRuleDefinitionQueryParams{},
+		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (map[string]any, error) {
+			errResponse := map[string]any{
+				"definition": make([]Info, 0),
+			}
+
+			queryParams, err := request.ToConcrete[*GetQueryRuleDefinitionQueryParams](params)
+			if err != nil {
+				return errResponse, err
+			}
+
+			return map[string]any{
+				"definition": formInfoBatch(GetQueryRuleDefinitions(queryParams.DomainName)),
+			}, nil
+		},
+	})
+}

+ 9 - 0
convenient/domain/query_rule/definition/entity.go

@@ -0,0 +1,9 @@
+package definition
+
+type Entity struct {
+	FieldType   string
+	FieldName   string
+	FieldCNName string
+	Operators   []Operator
+	ColumnName  string
+}

+ 35 - 0
convenient/domain/query_rule/definition/info.go

@@ -0,0 +1,35 @@
+package definition
+
+type Info struct {
+	FieldType   string     `json:"fieldType"`
+	FieldName   string     `json:"fieldName"`
+	FieldCNName string     `json:"fieldCNName"`
+	Operators   []Operator `json:"operators"`
+}
+
+func formInfo(e *Entity) Info {
+	if e == nil {
+		return Info{}
+	}
+
+	return Info{
+		FieldType:   e.FieldType,
+		FieldName:   e.FieldName,
+		FieldCNName: e.FieldCNName,
+		Operators:   e.Operators,
+	}
+}
+
+func formInfoBatch(es []Entity) []Info {
+	infos := make([]Info, 0)
+
+	if es == nil || len(es) == 0 {
+		return infos
+	}
+
+	for _, e := range es {
+		infos = append(infos, formInfo(&e))
+	}
+
+	return infos
+}

+ 50 - 44
convenient/domain/query_rule/query_rule_definition.go → convenient/domain/query_rule/definition/operator.go

@@ -1,11 +1,18 @@
-package query_rule
+package definition
 
 import (
-	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
+	"git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/clause"
 	"git.sxidc.com/go-framework/baize/framework/core/tag/rule"
-	"sync"
+	"git.sxidc.com/go-tools/utils/reflectutils"
+	"github.com/pkg/errors"
+	"reflect"
 )
 
+type Operator struct {
+	Name   string `json:"name"`
+	CNName string `json:"cnName"`
+}
+
 const (
 	opEqual              = "eq"
 	opNotEqual           = "ne"
@@ -114,57 +121,56 @@ var operatorOfTypeMap = map[string][]Operator{
 	},
 }
 
-var registeredDomainMap = &sync.Map{}
-
-type Operator struct {
-	Name   string `json:"name"`
-	CNName string `json:"cnName"`
-}
-
-type QueryRuleDefinitionItem struct {
-	FieldType   string     `json:"fieldType"`
-	FieldName   string     `json:"fieldName"`
-	FieldCNName string     `json:"fieldCNName"`
-	ColumnName  string     `json:"columnName"`
-	Operators   []Operator `json:"operators"`
-}
+func AddCondition(conditions *clause.Conditions, op string, columnName string, value any) error {
+	switch op {
+	case opEqual:
+		conditions.Equal(columnName, value)
+	case opNotEqual:
+		conditions.Not(columnName, value)
+	case opLessThan:
+		conditions.LessThan(columnName, value)
+	case opLessThanOrEqual:
+		conditions.LessThanAndEqual(columnName, value)
+	case opGreaterThan:
+		conditions.GreaterThan(columnName, value)
+	case opGreaterThanOrEqual:
+		conditions.GreaterThanAndEqual(columnName, value)
+	case opIn:
+		if reflect.TypeOf(value).Kind() != reflect.Slice {
+			return errors.New("使用\"包含在列表\"操作符必须使用列表")
+		}
 
-type RegisterQueryRuleDefinitionsByEntityItem struct {
-	Entity   entity.Entity
-	FieldMap map[string]string
-}
+		conditions.In(columnName, value)
+	case opNotIn:
+		if reflect.TypeOf(value).Kind() != reflect.Slice {
+			return errors.New("使用\"不包含在列表\"操作符必须使用列表")
+		}
 
-func RegisterQueryRuleDefinitionByEntity(items ...RegisterQueryRuleDefinitionsByEntityItem) error {
-	for _, item := range items {
-		e := item.Entity
+		conditions.NotIn(columnName, value)
+	case opPrefix:
+		strValue, err := reflectutils.ToString(value)
+		if err != nil {
+			return err
+		}
 
-		fields, err := rule.DefaultUsage(e)
+		conditions.Like(columnName, strValue+"%")
+	case opSuffix:
+		strValue, err := reflectutils.ToString(value)
 		if err != nil {
 			return err
 		}
 
-		definitions := make([]QueryRuleDefinitionItem, 0)
-		for _, field := range fields {
-			definitions = append(definitions, QueryRuleDefinitionItem{
-				FieldType:   field.Type,
-				FieldName:   field.FieldName,
-				ColumnName:  field.ColumnName,
-				FieldCNName: item.FieldMap[field.FieldName],
-				Operators:   operatorOfTypeMap[field.Type],
-			})
+		conditions.Like(columnName, "%"+strValue)
+	case opContains:
+		strValue, err := reflectutils.ToString(value)
+		if err != nil {
+			return err
 		}
 
-		registeredDomainMap.Store(e.DomainCamelName(), definitions)
+		conditions.Like(columnName, "%"+strValue+"%")
+	default:
+		return errors.Errorf("不支持的操作符%v", op)
 	}
 
 	return nil
 }
-
-func GetQueryRuleDefinition(domainName string) []QueryRuleDefinitionItem {
-	result, ok := registeredDomainMap.Load(domainName)
-	if !ok {
-		return make([]QueryRuleDefinitionItem, 0)
-	}
-
-	return result.([]QueryRuleDefinitionItem)
-}

+ 66 - 0
convenient/domain/query_rule/definition/register.go

@@ -0,0 +1,66 @@
+package definition
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
+	"git.sxidc.com/go-framework/baize/framework/core/tag/rule"
+	"github.com/pkg/errors"
+	"sync"
+)
+
+var registeredDomainMap = &sync.Map{}
+
+type RegisterByEntityItem struct {
+	Entity   entity.Entity
+	FieldMap map[string]string
+}
+
+func RegisterByDomainEntity(items ...RegisterByEntityItem) error {
+	for _, item := range items {
+		e := item.Entity
+
+		fields, err := rule.DefaultUsage(e)
+		if err != nil {
+			return err
+		}
+
+		definitions := make([]Entity, 0)
+		for _, field := range fields {
+			definitions = append(definitions, Entity{
+				FieldType:   field.Type,
+				FieldName:   field.FieldName,
+				ColumnName:  field.ColumnName,
+				FieldCNName: item.FieldMap[field.FieldName],
+				Operators:   operatorOfTypeMap[field.Type],
+			})
+		}
+
+		registeredDomainMap.Store(e.DomainCamelName(), definitions)
+	}
+
+	return nil
+}
+
+func GetQueryRuleDefinitions(domainName string) []Entity {
+	result, ok := registeredDomainMap.Load(domainName)
+	if !ok {
+		return make([]Entity, 0)
+	}
+
+	return result.([]Entity)
+}
+
+func GetColumnName(domainName string, fieldName string) (string, error) {
+	definitions := GetQueryRuleDefinitions(domainName)
+
+	if definitions == nil || len(definitions) == 0 {
+		return "", errors.Errorf("领域没有注册: %v", domainName)
+	}
+
+	for _, definition := range definitions {
+		if definition.FieldName == fieldName {
+			return definition.ColumnName, nil
+		}
+	}
+
+	return "", errors.Errorf("领域没有该字段: %v", fieldName)
+}

+ 7 - 0
convenient/domain/query_rule/definition/request_params.go

@@ -0,0 +1,7 @@
+package definition
+
+type (
+	GetQueryRuleDefinitionQueryParams struct {
+		DomainName string `form:"domainName" binding:"required" assign:"toField:DomainName"`
+	}
+)

+ 25 - 0
convenient/domain/query_rule/query_rule.go

@@ -0,0 +1,25 @@
+package query_rule
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/domain/query_rule/definition"
+	"git.sxidc.com/go-framework/baize/convenient/domain/query_rule/rule"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+// Simple Bind参数
+type Simple struct {
+	// schema
+	Schema string
+}
+
+func (simple *Simple) bind(binder *binding.Binder) {
+	(&definition.Simple{Schema: simple.Schema}).Bind(binder)
+	(&rule.Simple{Schema: simple.Schema}).Bind(binder)
+}
+
+func Bind(app *application.App, simple *Simple) {
+	binder := binding.NewBinder(app.Api().ChooseRouter(api.RouterPrefix, ""), app.Infrastructure())
+	simple.bind(binder)
+}

+ 2 - 29
convenient/domain/query_rule/api.go → convenient/domain/query_rule/rule/api.go

@@ -1,4 +1,4 @@
-package query_rule
+package rule
 
 import (
 	"git.sxidc.com/go-framework/baize/convenient/entity_crud"
@@ -6,7 +6,6 @@ import (
 	"git.sxidc.com/go-framework/baize/framework/core/api"
 	"git.sxidc.com/go-framework/baize/framework/core/api/request"
 	"git.sxidc.com/go-framework/baize/framework/core/api/response"
-	"git.sxidc.com/go-framework/baize/framework/core/application"
 	"git.sxidc.com/go-framework/baize/framework/core/domain"
 	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
 	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
@@ -22,30 +21,9 @@ type Simple struct {
 	Schema string
 }
 
-func (simple *Simple) bind(binder *binding.Binder) {
+func (simple *Simple) Bind(binder *binding.Binder) {
 	queryRuleTableName := domain.TableName(simple.Schema, &Entity{})
 
-	binding.GetBind(binder, &binding.SimpleBindItem[map[string]any]{
-		Path:             "/queryRuleDefinition/get",
-		SendResponseFunc: response.SendMapResponse,
-		RequestParams:    &GetQueryRuleDefinitionQueryParams{},
-		Objects:          []domain.Object{&Entity{}},
-		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (map[string]any, error) {
-			errResponse := map[string]any{
-				"definition": make([]QueryRuleDefinitionItem, 0),
-			}
-
-			e, err := domain.ToConcrete[*Entity](objects[0])
-			if err != nil {
-				return errResponse, err
-			}
-
-			return map[string]any{
-				"definition": GetQueryRuleDefinition(e.DomainName),
-			}, nil
-		},
-	})
-
 	entity_crud.BindSimple(binder,
 		&entity_crud.Simple[any]{
 			Entity:            &Entity{},
@@ -230,8 +208,3 @@ func (simple *Simple) bind(binder *binding.Binder) {
 		},
 	})
 }
-
-func Bind(app *application.App, simple *Simple) {
-	binder := binding.NewBinder(app.Api().ChooseRouter(api.RouterPrefix, ""), app.Infrastructure())
-	simple.bind(binder)
-}

+ 15 - 2
convenient/domain/query_rule/entity.go → convenient/domain/query_rule/rule/entity.go

@@ -1,9 +1,11 @@
-package query_rule
+package rule
 
 import (
+	"encoding/json"
 	"git.sxidc.com/go-framework/baize/framework/core/domain"
 	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
 	"git.sxidc.com/go-framework/baize/framework/core/tag/check"
+	"github.com/pkg/errors"
 )
 
 const (
@@ -65,7 +67,7 @@ func (e *Entity) ForCreate() error {
 		return err
 	}
 
-	err = Lint(e.Rule)
+	err = e.lintRule()
 	if err != nil {
 		return err
 	}
@@ -87,3 +89,14 @@ func (e *Entity) ForDelete() error {
 func (e *Entity) ForUpdate() error {
 	return nil
 }
+
+func (e *Entity) lintRule() error {
+	r := new(Rule)
+
+	err := json.Unmarshal([]byte(e.Rule), r)
+	if err != nil {
+		return errors.New(err.Error())
+	}
+
+	return r.check()
+}

+ 1 - 1
convenient/domain/query_rule/info.go → convenient/domain/query_rule/rule/info.go

@@ -1,4 +1,4 @@
-package query_rule
+package rule
 
 import "git.sxidc.com/go-framework/baize/framework/core/application"
 

+ 34 - 81
convenient/domain/query_rule/query_rule_parser.go → convenient/domain/query_rule/rule/query_rule_parser.go

@@ -1,17 +1,16 @@
-package query_rule
+package rule
 
 import (
 	"encoding/json"
+	"git.sxidc.com/go-framework/baize/convenient/domain/query_rule/definition"
 	"git.sxidc.com/go-framework/baize/framework/core/domain"
 	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
 	"git.sxidc.com/go-framework/baize/framework/core/infrastructure/database"
 	"git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/clause"
 	"git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/sql"
 	"git.sxidc.com/go-framework/baize/framework/core/tag/rule"
-	"git.sxidc.com/go-tools/utils/reflectutils"
 	"git.sxidc.com/go-tools/utils/strutils"
 	"github.com/pkg/errors"
-	"reflect"
 )
 
 const (
@@ -28,14 +27,13 @@ type Rule struct {
 	Left            *Rule  `json:"left"`
 	Right           *Rule  `json:"right"`
 
-	FieldName  string `json:"fieldName"`
-	FieldType  string `json:"fieldType"`
-	ColumnName string `json:"columnName"`
-	Operator   string `json:"operator"`
-	Value      any    `json:"value"`
+	FieldName string `json:"fieldName"`
+	FieldType string `json:"fieldType"`
+	Operator  string `json:"operator"`
+	Value     any    `json:"value"`
 }
 
-func (r Rule) Check() error {
+func (r Rule) check() error {
 	if strutils.IsStringNotEmpty(r.LogicalOperator) {
 		return r.checkAsNode()
 	} else {
@@ -92,27 +90,22 @@ func (r Rule) checkAsLeaf() error {
 		return errors.New("字段类型不支持")
 	}
 
-	if strutils.IsStringEmpty(r.ColumnName) {
-		return errors.New("列名为空")
-	}
-
-	if !IsSupportedOperator(r.Operator) {
+	if !definition.IsSupportedOperator(r.Operator) {
 		return errors.New("操作符不支持")
 	}
 
 	return nil
 }
 
-func Lint(ruleStr string) error {
-	r := new(Rule)
-	err := json.Unmarshal([]byte(ruleStr), r)
-	if err != nil {
-		return errors.New(err.Error())
-	}
-
-	return r.Check()
-}
-
+// HasRule 检查是否存在规则
+// 参数:
+// - dbSchema: 数据库schema
+// - scope: 范围
+// - domainName: 领域名称
+// - i: 基础设施
+// 返回值:
+// - 是否存在规则
+// - 错误
 func HasRule(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (bool, error) {
 	dbExecutor := i.DBExecutor()
 
@@ -125,7 +118,7 @@ func HasRule(dbSchema string, scope string, domainName string, i *infrastructure
 	})
 }
 
-// GetRulesAndFormConditionClause 获取规则并返回条件语句
+// FormConditionClause 获取规则并返回条件语句
 // 参数:
 // - dbSchema: 数据库schema
 // - scope: 范围
@@ -135,13 +128,13 @@ func HasRule(dbSchema string, scope string, domainName string, i *infrastructure
 // 返回值:
 // - 语句接口,当错误为nil时,语句接口也可能是nil,代表该规则并没有被赋值,所以是没有条件的
 // - 错误
-func GetRulesAndFormConditionClause(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure, ruleParams map[string]any) (clause.Clause, error) {
-	r, err := getRule(dbSchema, scope, domainName, i)
+func FormConditionClause(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure, ruleParams map[string]any) (clause.Clause, error) {
+	r, err := getEnabledRule(dbSchema, scope, domainName, i)
 	if err != nil {
 		return nil, err
 	}
 
-	c, err := formConditionClause(r, ruleParams)
+	c, err := formConditionClause(domainName, r, ruleParams)
 	if err != nil {
 		return nil, err
 	}
@@ -149,7 +142,7 @@ func GetRulesAndFormConditionClause(dbSchema string, scope string, domainName st
 	return c, nil
 }
 
-func getRule(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (Rule, error) {
+func getEnabledRule(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (Rule, error) {
 	dbExecutor := i.DBExecutor()
 
 	result, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{
@@ -172,10 +165,15 @@ func getRule(dbSchema string, scope string, domainName string, i *infrastructure
 	return *r, nil
 }
 
-func formConditionClause(r Rule, ruleParams map[string]any) (clause.Clause, error) {
+func formConditionClause(domainName string, r Rule, ruleParams map[string]any) (clause.Clause, error) {
 	if strutils.IsStringEmpty(r.LogicalOperator) {
+		columnName, err := definition.GetColumnName(domainName, r.FieldName)
+		if err != nil {
+			return nil, err
+		}
+
 		ruleValue := r.Value
-		ruleParamValue, ok := ruleParams[r.ColumnName]
+		ruleParamValue, ok := ruleParams[columnName]
 		if ok {
 			ruleValue = ruleParamValue
 		}
@@ -186,65 +184,20 @@ func formConditionClause(r Rule, ruleParams map[string]any) (clause.Clause, erro
 
 		conditions := clause.NewConditions()
 
-		switch r.Operator {
-		case opEqual:
-			conditions.Equal(r.ColumnName, ruleValue)
-		case opNotEqual:
-			conditions.Not(r.ColumnName, ruleValue)
-		case opLessThan:
-			conditions.LessThan(r.ColumnName, ruleValue)
-		case opLessThanOrEqual:
-			conditions.LessThanAndEqual(r.ColumnName, ruleValue)
-		case opGreaterThan:
-			conditions.GreaterThan(r.ColumnName, ruleValue)
-		case opGreaterThanOrEqual:
-			conditions.GreaterThanAndEqual(r.ColumnName, ruleValue)
-		case opIn:
-			if reflect.TypeOf(ruleValue).Kind() != reflect.Slice {
-				return nil, errors.New("使用\"包含在列表\"操作符必须使用列表")
-			}
-
-			conditions.In(r.ColumnName, ruleValue)
-		case opNotIn:
-			if reflect.TypeOf(ruleValue).Kind() != reflect.Slice {
-				return nil, errors.New("使用\"不包含在列表\"操作符必须使用列表")
-			}
-
-			conditions.NotIn(r.ColumnName, ruleValue)
-		case opPrefix:
-			strValue, err := reflectutils.ToString(ruleValue)
-			if err != nil {
-				return nil, err
-			}
-
-			conditions.Like(r.ColumnName, strValue+"%")
-		case opSuffix:
-			strValue, err := reflectutils.ToString(ruleValue)
-			if err != nil {
-				return nil, err
-			}
-
-			conditions.Like(r.ColumnName, "%"+strValue)
-		case opContains:
-			strValue, err := reflectutils.ToString(ruleValue)
-			if err != nil {
-				return nil, err
-			}
-
-			conditions.Like(r.ColumnName, "%"+strValue+"%")
-		default:
-			return nil, errors.Errorf("不支持的操作符%v", r.Operator)
+		err = definition.AddCondition(conditions, r.Operator, columnName, ruleValue)
+		if err != nil {
+			return nil, err
 		}
 
 		return conditions.And(), nil
 	}
 
-	leftClause, err := formConditionClause(*r.Left, ruleParams)
+	leftClause, err := formConditionClause(domainName, *r.Left, ruleParams)
 	if err != nil {
 		return nil, err
 	}
 
-	rightClause, err := formConditionClause(*r.Right, ruleParams)
+	rightClause, err := formConditionClause(domainName, *r.Right, ruleParams)
 	if err != nil {
 		return nil, err
 	}

+ 1 - 5
convenient/domain/query_rule/request_params.go → convenient/domain/query_rule/rule/request_params.go

@@ -1,12 +1,8 @@
-package query_rule
+package rule
 
 import "git.sxidc.com/go-framework/baize/framework/core/api/request"
 
 type (
-	GetQueryRuleDefinitionQueryParams struct {
-		DomainName string `form:"domainName" binding:"required" assign:"toField:DomainName"`
-	}
-
 	AddQueryRuleJsonBody struct {
 		Scope      string `json:"scope" binding:"required" assign:"toField:Scope"`
 		DomainName string `json:"domainName" binding:"required" assign:"toField:DomainName"`