Kaynağa Gözat

fix:
1. single中为类型增加别名
2. 增加multi功能(当前只支持多点位 and 逻辑)

gaoyagang 1 yıl önce
ebeveyn
işleme
7401bcf459
4 değiştirilmiş dosya ile 141 ekleme ve 16 silme
  1. 55 0
      identify/multi.go
  2. 24 0
      identify/multi_test.go
  3. 48 11
      identify/single.go
  4. 14 5
      identify/types.go

+ 55 - 0
identify/multi.go

@@ -0,0 +1,55 @@
+package identify
+
+import "encoding/json"
+
+type MultiItem struct {
+	nvs map[ItemName]ItemValue // 当前值
+	ovs map[ItemName]ItemValue // 上一次的值
+
+	rules map[EventName]MultiRule
+}
+
+func (m *MultiItem) Check(ovs, nvs map[ItemName]ItemValue) EventName {
+	m.ovs = ovs
+	m.nvs = nvs
+	defer func() {
+		m.ovs = nil
+		m.nvs = nil
+	}()
+
+	for eventName, multiRule := range m.rules {
+		if m.check(multiRule) {
+			return eventName
+		}
+	}
+
+	return ""
+}
+
+func (m *MultiItem) check(rules MultiRule) bool {
+	s := newSingleCheckForMultiItem()
+	// 判断指定的点位名, 是否通过了检测, 有一项不为true, 提前返回false
+	for itemName, rule := range rules {
+		if s.checkForMulti(m.ovs[itemName], m.nvs[itemName], rule) == false {
+			return false
+		}
+	}
+
+	return true
+}
+
+func NewMultiCheck(rules map[EventName]MultiRule) *MultiItem {
+	return &MultiItem{
+		rules: rules,
+	}
+}
+
+func MultiTest(ovs, nvs map[ItemName]ItemValue, ruleString string) string {
+	rules := make(map[EventName]MultiRule)
+	err := json.Unmarshal([]byte(ruleString), &rules)
+	if err != nil {
+		println(err.Error())
+	}
+
+	return NewMultiCheck(rules).Check(ovs, nvs)
+}

+ 24 - 0
identify/multi_test.go

@@ -0,0 +1,24 @@
+package identify
+
+import (
+	"testing"
+)
+
+func TestNewMultiCheck(t *testing.T) {
+	//map[string]MultiRule{}
+	ruleString := `{"过滤初期":{"step":{"NvIn":["26"]},"filter_time":{"NvIn":["360...660"]}}}`
+
+	ovs := map[string]string{
+		"step":        "25",
+		"filter_time": "361",
+	}
+
+	nvs := map[string]string{
+		"step":        "26",
+		"filter_time": "660",
+	}
+
+	eventName := MultiTest(ovs, nvs, ruleString)
+
+	t.Log(eventName)
+}

+ 48 - 11
identify/single.go

@@ -30,13 +30,13 @@ import (
 //	     ......
 //	}
 type SingleItem struct {
-	nv string // 当前值
-	ov string // 上一次的值
+	nv ItemValue // 当前值
+	ov ItemValue // 上一次的值
 
-	rules map[string]Rule
+	rules map[EventName]Rule
 }
 
-func (s *SingleItem) Check(ov, nv string) string {
+func (s *SingleItem) Check(ov, nv ItemValue) EventName {
 	defer func() {
 		s.nv = ""
 		s.ov = ""
@@ -51,6 +51,38 @@ func (s *SingleItem) Check(ov, nv string) string {
 	return ""
 }
 
+func (s *SingleItem) checkForMulti(ov, nv ItemValue, rule Rule) bool {
+	if ov == "" || nv == "" {
+		return false
+	}
+
+	s.ov = ov
+	s.nv = nv
+	defer func() {
+		s.nv = ""
+		s.ov = ""
+	}()
+
+	var ovIn, ovNotIn, nvIn, nvNotIn = true, true, true, true
+	if rule.OvIn != nil {
+		ovIn = s.ovIn(rule.OvIn)
+	}
+
+	if rule.OvNotIn != nil {
+		ovNotIn = s.ovNotIn(rule.OvNotIn)
+	}
+
+	if rule.NvIn != nil {
+		nvIn = s.nvIn(rule.NvIn)
+	}
+
+	if rule.NvNotIn != nil {
+		nvNotIn = s.nvNotIn(rule.NvNotIn)
+	}
+
+	return ovIn && ovNotIn && nvIn && nvNotIn
+}
+
 func (s *SingleItem) check(rule Rule) bool {
 	if s.ov == "" || s.nv == "" {
 		return false
@@ -76,7 +108,7 @@ func (s *SingleItem) check(rule Rule) bool {
 	return ovIn && ovNotIn && nvIn && nvNotIn
 }
 
-func (s *SingleItem) ovIn(slice []string) bool {
+func (s *SingleItem) ovIn(slice []ItemValue) bool {
 	b := true
 	if slice != nil && s.inSlice(slice, s.ov) == false {
 		b = false
@@ -84,7 +116,7 @@ func (s *SingleItem) ovIn(slice []string) bool {
 	return b
 }
 
-func (s *SingleItem) ovNotIn(slice []string) bool {
+func (s *SingleItem) ovNotIn(slice []ItemValue) bool {
 	b := true
 	if slice != nil && s.inSlice(slice, s.ov) == true {
 		b = false
@@ -92,7 +124,7 @@ func (s *SingleItem) ovNotIn(slice []string) bool {
 	return b
 }
 
-func (s *SingleItem) nvIn(slice []string) bool {
+func (s *SingleItem) nvIn(slice []ItemValue) bool {
 	b := true
 	if slice != nil && s.inSlice(slice, s.nv) == false {
 		b = false
@@ -100,7 +132,7 @@ func (s *SingleItem) nvIn(slice []string) bool {
 	return b
 }
 
-func (s *SingleItem) nvNotIn(slice []string) bool {
+func (s *SingleItem) nvNotIn(slice []ItemValue) bool {
 	b := true
 	if slice != nil && s.inSlice(slice, s.nv) == true {
 		b = false
@@ -108,7 +140,7 @@ func (s *SingleItem) nvNotIn(slice []string) bool {
 	return b
 }
 
-func (s *SingleItem) inSlice(slice []string, v string) bool {
+func (s *SingleItem) inSlice(slice []ItemValue, v ItemValue) bool {
 	for _, s2 := range slice {
 		s1 := s.transVar(s2)
 
@@ -123,7 +155,7 @@ func (s *SingleItem) inSlice(slice []string, v string) bool {
 	return false
 }
 
-func (s *SingleItem) transVar(v string) string {
+func (s *SingleItem) transVar(v ItemValue) ItemValue {
 	if v == VAR_NV {
 		v = s.nv
 	}
@@ -208,12 +240,17 @@ func (s *SingleItem) compareLogic(r string, v string) bool {
 }
 
 // NewSingleCheck 生成一个检测对象, 之后调用Check来获得事件名称
-func NewSingleCheck(rules map[string]Rule) *SingleItem {
+func NewSingleCheck(rules map[EventName]Rule) *SingleItem {
 	return &SingleItem{
 		rules: rules,
 	}
 }
 
+// NewSingleCheck 生成一个检测对象, 之后调用Check来获得事件名称
+func newSingleCheckForMultiItem() *SingleItem {
+	return &SingleItem{}
+}
+
 func StepTest(ov, nv, ruleString string) string {
 	rules := make(map[string]Rule)
 	err := json.Unmarshal([]byte(ruleString), &rules)

+ 14 - 5
identify/types.go

@@ -5,14 +5,23 @@ import (
 	"encoding/json"
 )
 
+// ItemName 点位名称
+type ItemName = string
+
+// EventName 事件名称
+type EventName = string
+
+// ItemValue 点位值
+type ItemValue = string
+
 type Rule struct {
-	NvIn    []string `json:"NvIn"`
-	NvNotIn []string `json:"NvNotIn"`
-	OvIn    []string `json:"OvIn"`
-	OvNotIn []string `json:"OvNotIn"`
+	NvIn    []ItemValue `json:"NvIn"`
+	NvNotIn []ItemValue `json:"NvNotIn"`
+	OvIn    []ItemValue `json:"OvIn"`
+	OvNotIn []ItemValue `json:"OvNotIn"`
 }
 
-type MultiRule []Rule
+type MultiRule map[ItemName]Rule
 
 // Scan 实现方法
 func (d *MultiRule) Scan(input interface{}) error {