Browse Source

添加基于查询规则的高级查询接口添加

yjp 2 months ago
parent
commit
7c544ec172

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

@@ -5,7 +5,18 @@ import (
 	"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/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"
+	"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-tools/utils/strutils"
+	"github.com/goccy/go-json"
+	"github.com/pkg/errors"
 )
 
 // Simple Bind参数
@@ -23,3 +34,106 @@ func Bind(app *application.App, simple *Simple) {
 	binder := binding.NewBinder(app.Api().ChooseRouter(api.RouterPrefix, ""), app.Infrastructure())
 	simple.bind(binder)
 }
+
+type BaseAdvanceQueryParams struct {
+	Rule     string `json:"rule" assign:"-"`
+	PageNo   int    `json:"pageNo" assign:"-"`
+	PageSize int    `json:"pageSize" assign:"-"`
+}
+
+type AddUseQueryRuleQueryRouteParams struct {
+	DBSchema         string
+	DomainPath       string
+	Object           domain.Object
+	QueryMiddlewares []binding.Middleware
+}
+
+func AddUseQueryRuleQueryRoute[O any](binder *binding.Binder, addParams *AddUseQueryRuleQueryRouteParams) {
+	binding.PostBind(binder, &binding.SimpleBindItem[response.InfosData[O]]{
+		Path:             addParams.DomainPath + "/advancedQuery",
+		SendResponseFunc: response.SendInfosResponse[O],
+		RequestParams:    &BaseAdvanceQueryParams{},
+		Objects:          []domain.Object{addParams.Object},
+		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (response.InfosData[O], error) {
+			errResponse := response.InfosData[O]{
+				Infos: make([]O, 0),
+			}
+
+			if params == nil {
+				return errResponse, errors.New("请求参数为空")
+			}
+
+			object := objects[0]
+			if object == nil {
+				return errResponse, errors.New("领域实体为空")
+			}
+
+			queryParams, ok := params.(*BaseAdvanceQueryParams)
+			if !ok {
+				return errResponse, errors.New("请求参数不是Query接口")
+			}
+
+			e, ok := objects[0].(entity.Entity)
+			if !ok {
+				return errResponse, errors.New("需要传递领域对象应该为实体")
+			}
+
+			var selectClause *clause.Select
+			var countClause *clause.Select
+
+			fromClause := clause.NewFrom([]clause.Clause{clause.TableName(domain.TableName(addParams.DBSchema, e))})
+			limitClause := clause.NewLimit(queryParams.PageNo, queryParams.PageSize)
+
+			if strutils.IsStringEmpty(queryParams.Rule) {
+				selectClause = clause.NewSelect(nil, fromClause, limitClause)
+				countClause = clause.NewSelect([]string{"COUNT(*) AS total"}, fromClause)
+			} else {
+				queryRule := new(rule.Rule)
+				err := json.Unmarshal([]byte(queryParams.Rule), queryRule)
+				if err != nil {
+					return errResponse, err
+				}
+
+				conditionClause, err := rule.FormConditionClauseByRules(e.DomainCamelName(), *queryRule, nil)
+				if err != nil {
+					return errResponse, err
+				}
+
+				selectClause = clause.NewSelect(nil, fromClause, clause.NewWhere(conditionClause), limitClause)
+				countClause = clause.NewSelect([]string{"COUNT(*) AS total"}, fromClause, clause.NewWhere(conditionClause))
+			}
+
+			selectClauseStr, err := selectClause.Clause()
+			if err != nil {
+				return errResponse, err
+			}
+
+			results, err := database.ExecuteRawSql(i.DBExecutor(), selectClauseStr, selectClause.Args()...)
+			if err != nil {
+				return errResponse, err
+			}
+
+			countClauseStr, err := countClause.Clause()
+			if err != nil {
+				return errResponse, err
+			}
+
+			countResults, err := database.ExecuteRawSql(i.DBExecutor(), countClauseStr, countClause.Args()...)
+			if err != nil {
+				return errResponse, err
+			}
+
+			infos := make([]O, 0)
+			err = sql.ParseSqlResult(results, &infos)
+			if err != nil {
+				return errResponse, err
+			}
+
+			return response.InfosData[O]{
+				Infos:      infos,
+				TotalCount: countResults[0].ColumnValueInt64("total"),
+				PageNo:     queryParams.PageNo,
+			}, nil
+		},
+	}, addParams.QueryMiddlewares...)
+}

+ 1 - 14
convenient/domain/query_rule/rule/api.go

@@ -33,20 +33,7 @@ func (simple *Simple) Bind(binder *binding.Binder) {
 		},
 		entity_crud.WithDisableUpdate(),
 		entity_crud.WithDisableQuery[any](),
-		entity_crud.WithDisableGetByID[any](),
-		entity_crud.WithCreateCallbacks(&entity_crud.CreateCallbacks{
-			Before: func(c *api.Context, params request.Params, e entity.Entity, prepared map[string]any, i *infrastructure.Infrastructure, tx database.Executor) error {
-				ruleEntity, err := domain.ToConcrete[*Entity](e)
-				if err != nil {
-					return err
-				}
-
-				return ruleEntity.LintRule()
-			},
-			After:           nil,
-			OnSuccessReturn: nil,
-			OnErrorReturn:   nil,
-		}))
+		entity_crud.WithDisableGetByID[any]())
 
 	binding.PostBind(binder, &binding.SimpleBindItem[response.InfosData[Info]]{
 		Path:             "/queryRule/query",

+ 0 - 13
convenient/domain/query_rule/rule/entity.go

@@ -1,10 +1,8 @@
 package rule
 
 import (
-	"encoding/json"
 	"git.sxidc.com/go-framework/baize/framework/core/domain"
 	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
-	"github.com/pkg/errors"
 )
 
 const (
@@ -46,14 +44,3 @@ func (e *Entity) DomainCamelName() string {
 func (e *Entity) GetFieldMap() map[string]string {
 	return fieldMap
 }
-
-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()
-}

+ 11 - 3
convenient/domain/query_rule/rule/query_rule_parser.go

@@ -184,6 +184,11 @@ func getEnabledRule(dbSchema string, scope string, domainName string, i *infrast
 }
 
 func formConditionClause(domainName string, r Rule, ruleParams map[string]any) (clause.Clause, error) {
+	err := r.check()
+	if err != nil {
+		return nil, err
+	}
+
 	if strutils.IsStringEmpty(r.LogicalOperator) {
 		columnName, err := definition.GetColumnName(domainName, r.FieldName)
 		if err != nil {
@@ -191,9 +196,12 @@ func formConditionClause(domainName string, r Rule, ruleParams map[string]any) (
 		}
 
 		ruleValue := r.Value
-		ruleParamValue, ok := ruleParams[columnName]
-		if ok {
-			ruleValue = ruleParamValue
+
+		if ruleParams != nil {
+			ruleParamValue, ok := ruleParams[columnName]
+			if ok {
+				ruleValue = ruleParamValue
+			}
 		}
 
 		if ruleValue == nil {