github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/validate/matcher/condition.go (about)

     1  package matcher
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/isyscore/isc-gobase/constants"
     6  	"reflect"
     7  	"strings"
     8  
     9  	"github.com/antonmedv/expr"
    10  	"github.com/antonmedv/expr/compiler"
    11  	"github.com/antonmedv/expr/parser"
    12  	"github.com/antonmedv/expr/vm"
    13  	"github.com/isyscore/isc-gobase/logger"
    14  )
    15  
    16  type ConditionMatch struct {
    17  	BlackWhiteMatch
    18  
    19  	expression string
    20  	Program    *vm.Program
    21  }
    22  
    23  func (conditionMatch *ConditionMatch) Match(_ map[string]interface{}, object any, field reflect.StructField, fieldValue any) bool {
    24  	env := map[string]any{
    25  		"root":    object,
    26  		"current": fieldValue,
    27  	}
    28  
    29  	output, err := expr.Run(conditionMatch.Program, env)
    30  	if err != nil {
    31  		logger.Error("表达式 %v 执行失败: %v", conditionMatch.expression, err.Error())
    32  		return false
    33  	}
    34  
    35  	result, err := CastBool(fmt.Sprintf("%v", output))
    36  	if err != nil {
    37  		return false
    38  	}
    39  
    40  	if result {
    41  		conditionMatch.SetBlackMsg("属性 %v 的值 %v 命中禁用条件 [%v] ", field.Name, fieldValue, conditionMatch.expression)
    42  	} else {
    43  		conditionMatch.SetWhiteMsg("属性 %v 的值 %v 不符合条件 [%v] ", field.Name, fieldValue, conditionMatch.expression)
    44  	}
    45  	return result
    46  }
    47  
    48  func (conditionMatch *ConditionMatch) IsEmpty() bool {
    49  	return conditionMatch.Program == nil
    50  }
    51  
    52  func BuildConditionMatcher(objectTypeFullName string, fieldKind reflect.Kind, objectFieldName string, tagName string, subCondition string, errMsg string) {
    53  	if constants.MATCH != tagName {
    54  		return
    55  	}
    56  
    57  	if fieldKind == reflect.Slice {
    58  		return
    59  	}
    60  	if !strings.Contains(subCondition, constants.Condition) || !strings.Contains(subCondition, constants.EQUAL) {
    61  		return
    62  	}
    63  
    64  	index := strings.Index(subCondition, constants.EQUAL)
    65  	expression := subCondition[index+1:]
    66  
    67  	if expression == "" {
    68  		return
    69  	}
    70  
    71  	tree, err := parser.Parse(rmvWell(expression))
    72  	if err != nil {
    73  		logger.Error("脚本:%v 解析异常:%v", expression, err.Error())
    74  		return
    75  	}
    76  
    77  	program, err := compiler.Compile(tree, nil)
    78  	if err != nil {
    79  		logger.Error("脚本: %v 编译异常:%v", expression, err.Error())
    80  		return
    81  	}
    82  	addMatcher(objectTypeFullName, objectFieldName, &ConditionMatch{Program: program, expression: expression}, errMsg, true)
    83  }