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 // 关闭记录查询规则 DisableRecordRule bool } func (simple *Simple) bind(binder *binding.Binder) { (&definition.Simple{Schema: simple.Schema}).Bind(binder) if !simple.DisableRecordRule { (&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 FormAdditionalSelectClausesFunc func(queryParams AdvanceQueryParams) ([]string, error) type FormAdditionalFromFunc func(queryParams AdvanceQueryParams) ([]clause.Clause, error) type FormAdditionalConditionsFunc func(queryParams AdvanceQueryParams) (clause.Clause, error) type FormOrderByFunc func(queryParams AdvanceQueryParams) (clause.Clause, error) type AddUseQueryRuleQueryRouteParams struct { DBSchema string QueryParams AdvanceQueryParams FormAdditionalSelectClausesFunc FormAdditionalSelectClausesFunc FormAdditionalFromFunc FormAdditionalFromFunc FormAdditionalConditionsFunc FormAdditionalConditionsFunc FormOrderByFunc FormOrderByFunc 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("需要传递领域对象应该为实体") } // 构造select语句块 selectClauses := make([]string, 0) if addParams.FormAdditionalSelectClausesFunc != nil { additionalSelectClauses, err := addParams.FormAdditionalSelectClausesFunc(advanceQueryParams) if err != nil { return errResponse, err } selectClauses = additionalSelectClauses } // 构造from语句块 fromClauses := []clause.Clause{clause.TableName(domain.TableName(addParams.DBSchema, e))} if addParams.FormAdditionalFromFunc != nil { additionalFromClauses, err := addParams.FormAdditionalFromFunc(advanceQueryParams) if err != nil { return errResponse, err } fromClauses = append(fromClauses, additionalFromClauses...) } // 构造where语句块 var conditionsClause clause.Clause if strutils.IsStringNotEmpty(advanceQueryParams.GetRule()) { queryRule := new(rule.Rule) err := json.Unmarshal([]byte(advanceQueryParams.GetRule()), queryRule) if err != nil { return errResponse, err } ruleConditionClause, err := rule.FormConditionClauseByRule(e.DomainCamelName(), *queryRule, nil) if err != nil { return errResponse, err } conditionsClause = ruleConditionClause } if addParams.FormAdditionalConditionsFunc != nil { additionalConditionsClause, err := addParams.FormAdditionalConditionsFunc(advanceQueryParams) if err != nil { return errResponse, err } conditionsClause = clause.NewConditionJoin(conditionsClause, additionalConditionsClause).And() } // 构造order by语句块 var orderByClause clause.Clause if addParams.FormOrderByFunc != nil { innerOrderByClause, err := addParams.FormOrderByFunc(advanceQueryParams) if err != nil { return errResponse, err } orderByClause = innerOrderByClause } // 构造limit语句块 limitClause := clause.NewLimit(advanceQueryParams.GetPageNo(), advanceQueryParams.GetPageSize()) fromClause := clause.NewFrom(fromClauses) selectClause := clause.NewSelect(selectClauses, fromClause, clause.NewWhere(conditionsClause), orderByClause, limitClause) countClause := clause.NewSelect([]string{"COUNT(*) AS total"}, fromClause, clause.NewWhere(conditionsClause)) 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...) }