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 }