| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- package query_rule
- import (
- "encoding/json"
- "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/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"
- "strings"
- )
- const (
- LogicalOperatorAnd = "and"
- LogicalOperatorOr = "or"
- )
- func isSupportedLogicalOperator(logicalOperator string) bool {
- return logicalOperator == LogicalOperatorAnd || logicalOperator == LogicalOperatorOr
- }
- type Rule struct {
- LogicalOperator string `json:"logical_operator"`
- 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"`
- }
- func (r Rule) Check() error {
- if strutils.IsStringNotEmpty(r.LogicalOperator) {
- return r.checkAsNode()
- } else {
- return r.checkAsLeaf()
- }
- }
- func (r Rule) checkAsNode() error {
- if !isSupportedLogicalOperator(r.LogicalOperator) {
- return errors.New("不支持的逻辑操作符")
- }
- if r.Left == nil {
- return errors.New("左结点为空")
- }
- if r.Right == nil {
- return errors.New("右结点为空")
- }
- if strutils.IsStringNotEmpty(r.Left.LogicalOperator) {
- err := r.Left.checkAsNode()
- if err != nil {
- return err
- }
- } else {
- err := r.Left.checkAsLeaf()
- if err != nil {
- return err
- }
- }
- if strutils.IsStringNotEmpty(r.Right.LogicalOperator) {
- err := r.Right.checkAsNode()
- if err != nil {
- return err
- }
- } else {
- err := r.Right.checkAsLeaf()
- if err != nil {
- return err
- }
- }
- return nil
- }
- func (r Rule) checkAsLeaf() error {
- if strutils.IsStringEmpty(r.FieldName) {
- return errors.New("字段名为空")
- }
- if !rule.IsSupportedType(r.FieldType) {
- return errors.New("字段类型不支持")
- }
- if strutils.IsStringEmpty(r.ColumnName) {
- return errors.New("列名为空")
- }
- if !IsSupportedOperator(r.Operator) {
- return errors.New("操作符不支持")
- }
- if r.Value == nil {
- return errors.New("没有传递值")
- }
- return nil
- }
- func Lint(ruleStr string) error {
- r := new(Rule)
- err := json.Unmarshal([]byte(ruleStr), r)
- if err != nil {
- return err
- }
- return r.Check()
- }
- func HasRule(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (bool, error) {
- dbExecutor := i.DBExecutor()
- return database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
- TableName: domain.TableName(dbSchema, &ValueObject{}),
- Conditions: sql.NewConditions().Equal(ColumnScope, scope).Equal(ColumnDomainName, domainName),
- })
- }
- func GetRulesAndFormConditionClause(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (string, []any, error) {
- r, err := getRule(dbSchema, scope, domainName, i)
- if err != nil {
- return "", nil, err
- }
- clause, args, err := formConditionClause(r)
- if err != nil {
- return "", nil, err
- }
- return clause, args, nil
- }
- func getRule(dbSchema string, scope string, domainName string, i *infrastructure.Infrastructure) (Rule, error) {
- dbExecutor := i.DBExecutor()
- result, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{
- TableName: domain.TableName(dbSchema, &ValueObject{}),
- Conditions: sql.NewConditions().Equal(ColumnScope, scope).Equal(ColumnDomainName, domainName),
- })
- if err != nil {
- return Rule{}, err
- }
- r := new(Rule)
- err = json.Unmarshal([]byte(result.ColumnValueString(ColumnRule)), r)
- if err != nil {
- return Rule{}, err
- }
- return *r, nil
- }
- func formConditionClause(r Rule) (string, []any, error) {
- if strutils.IsStringEmpty(r.LogicalOperator) {
- conditions := sql.NewConditions()
- switch r.Operator {
- case opEqual:
- conditions.Equal(r.ColumnName, r.Value)
- case opNotEqual:
- conditions.Not(r.ColumnName, r.Value)
- case opLessThan:
- conditions.LessThan(r.ColumnName, r.Value)
- case opLessThanOrEqual:
- conditions.LessThanAndEqual(r.ColumnName, r.Value)
- case opGreaterThan:
- conditions.GreaterThan(r.ColumnName, r.Value)
- case opGreaterThanOrEqual:
- conditions.GreaterThanAndEqual(r.ColumnName, r.Value)
- case opIn:
- if reflect.TypeOf(r.Value).Kind() != reflect.Slice {
- return "", nil, errors.New("使用\"包含在列表\"操作符必须使用列表")
- }
- conditions.In(r.FieldName, r.Value)
- case opNotIn:
- if reflect.TypeOf(r.Value).Kind() != reflect.Slice {
- return "", nil, errors.New("使用\"不包含在列表\"操作符必须使用列表")
- }
- conditions.NotIn(r.FieldName, r.Value)
- case opPrefix:
- strValue, err := reflectutils.ToString(r.Value)
- if err != nil {
- return "", nil, err
- }
- conditions.Like(r.FieldName, strValue+"%")
- case opSuffix:
- strValue, err := reflectutils.ToString(r.Value)
- if err != nil {
- return "", nil, err
- }
- conditions.Like(r.FieldName, "%"+strValue)
- case opContains:
- strValue, err := reflectutils.ToString(r.Value)
- if err != nil {
- return "", nil, err
- }
- conditions.Like(r.FieldName, "%"+strValue+"%")
- default:
- return "", nil, errors.Errorf("不支持的操作符%v", r.Operator)
- }
- return conditions.And(), conditions.Args(), nil
- }
- leftClause, leftArgs, err := formConditionClause(*r.Left)
- if err != nil {
- return "", nil, err
- }
- rightClause, rightArgs, err := formConditionClause(*r.Right)
- if err != nil {
- return "", nil, err
- }
- clauseBuilder := strings.Builder{}
- clauseBuilder.WriteString("(" + leftClause + ")")
- switch r.LogicalOperator {
- case LogicalOperatorAnd:
- clauseBuilder.WriteString(" AND ")
- case LogicalOperatorOr:
- clauseBuilder.WriteString(" OR ")
- }
- clauseBuilder.WriteString("(" + rightClause + ")")
- args := make([]any, 0)
- args = append(args, leftArgs...)
- args = append(args, rightArgs...)
- return clauseBuilder.String(), args, nil
- }
|