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/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参数 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) } type AdvanceQueryParams interface { GetRule() string GetPageNo() int GetPageSize() int } type BaseAdvanceQueryParams struct { Rule string `json:"rule" assign:"-"` PageNo int `json:"pageNo" assign:"-"` PageSize int `json:"pageSize" assign:"-"` } func (queryParams *BaseAdvanceQueryParams) GetRule() string { return queryParams.Rule } func (queryParams *BaseAdvanceQueryParams) GetPageNo() int { return queryParams.PageNo } func (queryParams *BaseAdvanceQueryParams) GetPageSize() int { return queryParams.PageSize } type FormAdditionalConditionsFunc func(queryParams AdvanceQueryParams) (clause.Clause, error) type AddUseQueryRuleQueryRouteParams struct { DBSchema string QueryParams AdvanceQueryParams FormAdditionalConditionsFunc FormAdditionalConditionsFunc Object domain.Object QueryMiddlewares []binding.Middleware } func AddUseQueryRuleQueryRoute[O any](binder *binding.Binder, addParams *AddUseQueryRuleQueryRouteParams) { domainPath := domain.RelativeDomainPath(addParams.Object) var queryParams AdvanceQueryParams queryParams = new(BaseAdvanceQueryParams) if addParams.QueryParams != nil { queryParams = addParams.QueryParams } binding.PostBind(binder, &binding.SimpleBindItem[response.InfosData[O]]{ Path: domainPath + "/advancedQuery", SendResponseFunc: response.SendInfosResponse[O], RequestParams: queryParams, 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("领域实体为空") } advanceQueryParams, ok := params.(AdvanceQueryParams) 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 var additionalConditions clause.Clause fromClause := clause.NewFrom([]clause.Clause{clause.TableName(domain.TableName(addParams.DBSchema, e))}) limitClause := clause.NewLimit(advanceQueryParams.GetPageNo(), advanceQueryParams.GetPageSize()) if addParams.FormAdditionalConditionsFunc != nil { conditions, err := addParams.FormAdditionalConditionsFunc(advanceQueryParams) if err != nil { return errResponse, err } additionalConditions = conditions } if strutils.IsStringEmpty(advanceQueryParams.GetRule()) { if additionalConditions != nil { selectClause = clause.NewSelect(nil, fromClause, clause.NewWhere(additionalConditions), limitClause) countClause = clause.NewSelect([]string{"COUNT(*) AS total"}, fromClause, clause.NewWhere(additionalConditions)) } else { selectClause = clause.NewSelect(nil, fromClause, limitClause) countClause = clause.NewSelect([]string{"COUNT(*) AS total"}, fromClause) } } else { queryRule := new(rule.Rule) err := json.Unmarshal([]byte(advanceQueryParams.GetRule()), queryRule) if err != nil { return errResponse, err } conditionClause, err := rule.FormConditionClauseByRules(e.DomainCamelName(), *queryRule, nil) if err != nil { return errResponse, err } if additionalConditions != nil { conditionClause = clause.NewConditionJoin(conditionClause, additionalConditions).And() } 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: advanceQueryParams.GetPageNo(), }, nil }, }, addParams.QueryMiddlewares...) }