package matcher import ( "encoding/json" "reflect" "strings" ctxpkg "github.com/noahlann/nnet/pkg/context" routerpkg "github.com/noahlann/nnet/pkg/router" ) // FrameDataMatcher 帧数据匹配器 type FrameDataMatcher struct { path string operator string value interface{} priority int } // NewFrameDataMatcher 创建帧数据匹配器 func NewFrameDataMatcher(path, operator string, value interface{}) routerpkg.Matcher { return &FrameDataMatcher{ path: path, operator: operator, value: value, priority: 150, // 帧数据匹配优先级低于帧头匹配 } } // WithPriority 设置优先级 func (m *FrameDataMatcher) WithPriority(priority int) *FrameDataMatcher { m.priority = priority return m } // Match 匹配帧数据 func (m *FrameDataMatcher) Match(input routerpkg.MatchInput, ctx ctxpkg.Context) bool { var parsedData interface{} if input.Data != nil { parsedData = input.Data } else if len(input.DataBytes) > 0 { var jsonData map[string]interface{} if err := json.Unmarshal(input.DataBytes, &jsonData); err != nil { return false } parsedData = jsonData } else if len(input.Raw) > 0 { var jsonData map[string]interface{} if err := json.Unmarshal(input.Raw, &jsonData); err != nil { return false } parsedData = jsonData } else if req := ctx.Request(); req != nil { if req.Data() != nil { parsedData = req.Data() } else if len(req.DataBytes()) > 0 { var jsonData map[string]interface{} if err := json.Unmarshal(req.DataBytes(), &jsonData); err != nil { return false } parsedData = jsonData } } if parsedData == nil { return false } // 根据路径提取值 fieldValue := m.extractValue(parsedData, m.path) if fieldValue == nil { return false } return m.compare(fieldValue, m.value, m.operator) } // extractValue 从数据中提取值(支持点号分隔的路径,如 "user.id") func (m *FrameDataMatcher) extractValue(data interface{}, path string) interface{} { if path == "" { return data } parts := strings.Split(path, ".") current := data for _, part := range parts { switch v := current.(type) { case map[string]interface{}: current = v[part] if current == nil { return nil } default: // 使用反射获取字段值 rv := reflect.ValueOf(current) if rv.Kind() == reflect.Ptr { rv = rv.Elem() } if rv.Kind() != reflect.Struct { return nil } field := rv.FieldByName(part) if !field.IsValid() { return nil } current = field.Interface() } } return current } // compare 比较值(与FrameHeaderMatcher相同的逻辑) func (m *FrameDataMatcher) compare(actual, expected interface{}, operator string) bool { switch operator { case "==": return reflect.DeepEqual(actual, expected) case "!=": return !reflect.DeepEqual(actual, expected) case ">": return m.greaterThan(actual, expected) case "<": return m.lessThan(actual, expected) case ">=": return m.greaterThan(actual, expected) || reflect.DeepEqual(actual, expected) case "<=": return m.lessThan(actual, expected) || reflect.DeepEqual(actual, expected) case "in": return m.in(actual, expected) case "contains": return m.contains(actual, expected) default: return false } } // greaterThan 大于比较 func (m *FrameDataMatcher) greaterThan(a, b interface{}) bool { switch av := a.(type) { case int: if bv, ok := b.(int); ok { return av > bv } case int32: if bv, ok := b.(int32); ok { return av > bv } case int64: if bv, ok := b.(int64); ok { return av > bv } case uint8: if bv, ok := b.(uint8); ok { return av > bv } case uint32: if bv, ok := b.(uint32); ok { return av > bv } case uint64: if bv, ok := b.(uint64); ok { return av > bv } case float64: if bv, ok := b.(float64); ok { return av > bv } } return false } // lessThan 小于比较 func (m *FrameDataMatcher) lessThan(a, b interface{}) bool { switch av := a.(type) { case int: if bv, ok := b.(int); ok { return av < bv } case int32: if bv, ok := b.(int32); ok { return av < bv } case int64: if bv, ok := b.(int64); ok { return av < bv } case uint8: if bv, ok := b.(uint8); ok { return av < bv } case uint32: if bv, ok := b.(uint32); ok { return av < bv } case uint64: if bv, ok := b.(uint64); ok { return av < bv } case float64: if bv, ok := b.(float64); ok { return av < bv } } return false } // in 检查是否在列表中 func (m *FrameDataMatcher) in(value, list interface{}) bool { listValue := reflect.ValueOf(list) if listValue.Kind() != reflect.Slice { return false } for i := 0; i < listValue.Len(); i++ { if reflect.DeepEqual(value, listValue.Index(i).Interface()) { return true } } return false } // contains 检查是否包含 func (m *FrameDataMatcher) contains(container, item interface{}) bool { // 字符串包含 if str, ok := container.(string); ok { if itemStr, ok := item.(string); ok { return strings.Contains(str, itemStr) } } // 数组/切片包含 containerValue := reflect.ValueOf(container) if containerValue.Kind() == reflect.Slice { for i := 0; i < containerValue.Len(); i++ { if reflect.DeepEqual(item, containerValue.Index(i).Interface()) { return true } } } return false } // Priority 获取优先级 func (m *FrameDataMatcher) Priority() int { return m.priority } // Path 获取路径 func (m *FrameDataMatcher) Path() string { return m.path } // Operator 获取操作符 func (m *FrameDataMatcher) Operator() string { return m.operator } // Value 获取匹配值 func (m *FrameDataMatcher) Value() interface{} { return m.value }