package service import ( "github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gctx" "log" "regexp" "strings" ) type Rule struct{} func (r *Rule) Execute(b *BidInfo) (string, int) { var bidCommonwealth int var quoteMode string if b.Type == 0 { bidCommonwealth = r.bidCommonwealth(b) quoteMode, _ = r.quoteMode(b) } else if b.Type == 1 { quoteMode, _ = r.quoteMode(b) } else if b.Type == 2 { bidCommonwealth = r.bidCommonwealth(b) } if quoteMode == QuoteMode_Whole && (b.Bidamount > 0 && b.Bidamount < g.Config().MustGet(gctx.New(), "quoteMode.minBidamount").Float64()) { quoteMode = "" } log.Println(b.Id, "规则", "报价模式", quoteMode, "中标联合体", bidCommonwealth) return quoteMode, bidCommonwealth } // 识别报价模式 func (r *Rule) quoteMode(b *BidInfo) (string, map[string]bool) { quoteModeRules := g.Config().MustGet(gctx.New(), "quoteMode.rules").Maps() for _, v := range quoteModeRules { vv := gvar.New(v).MapStrVar() mustTableKv := vv["mustTableKv"].Maps() modeName := vv["mode"].String() for _, table := range b.TableKv { array := []string{} for _, row := range table { mustTableKvMap := map[int]bool{} for k, v := range row { if tableV := vv["tableV"].String(); tableV != "" { matchedK, _ := regexp.MatchString(g.Config().MustGet(gctx.New(), "quoteMode.tableK").String(), k) if !matchedK { if tableK := vv["tableK"].String(); tableK != "" { matchedK, _ = regexp.MatchString(tableK, k) } } matchedV, _ := regexp.MatchString(tableV, v) if matchedK && matchedV { log.Println(b.Id, "tableKv", k, v) return modeName, nil } } // for _, vv := range vv["tableKv"].Maps() { vvs := gvar.New(vv).MapStrVar() tableK := vvs["k"].String() tableV := vvs["v"].String() if tableK == "" || tableV == "" { continue } matchedK, _ := regexp.MatchString(tableK, k) matchedV, _ := regexp.MatchString(tableV, v) if matchedK && matchedV { log.Println(b.Id, "tableKv", k, v) return modeName, nil } } // for kk, vv := range mustTableKv { vvs := gvar.New(vv).MapStrVar() tableK := vvs["k"].String() tableV := vvs["v"].String() if tableK == "" || tableV == "" { continue } matchedK, _ := regexp.MatchString(tableK, k) matchedV, _ := regexp.MatchString(tableV, v) if matchedK && matchedV { array = append(array, k+":"+v) mustTableKvMap[kk] = true break } } } for kk, _ := range mustTableKv { if !mustTableKvMap[kk] { break } if kk == len(mustTableKv)-1 { log.Println(b.Id, "mustTableKv", strings.Join(array, " ")) return modeName, nil } } } } } for _, v := range quoteModeRules { vv := gvar.New(v).MapStrVar() modeName := vv["mode"].String() detail := b.Detail for _, v := range vv["clearPatterns"].Strings() { detail = regexp.MustCompile(v).ReplaceAllString(detail, "") } excludePatterns := vv["excludePatterns"].Strings() if len(excludePatterns) > 0 && !r.matchAnyPattern(b.Id, detail, excludePatterns) { return modeName, nil } lines := strings.Split(detail, "\n") for _, lineVal := range lines { if r.matchAnyPattern(b.Id, lineVal, vv["patterns"].Strings()) { return modeName, nil } } } return "", nil } // 识别中标联合体 func (r *Rule) bidCommonwealth(b *BidInfo) int { // Step 1: 排除黑名单 if r.matchAnyPattern(b.Id, b.Detail, g.Config().MustGet(gctx.New(), "bidCommonwealth.blacklistPatterns").Strings()) { return -1 } detail := b.Detail for _, v := range g.Config().MustGet(gctx.New(), "bidCommonwealth.clearPatterns").Strings() { detail = regexp.MustCompile(v).ReplaceAllString(detail, "") } if r.matchAnyPattern(b.Id, b.Detail, g.Config().MustGet(gctx.New(), "bidCommonwealth.whitelistPatterns").Strings()) { return 1 } return -1 } // 匹配任意模式 func (r *Rule) matchAnyPattern(_id string, text string, patterns []string) bool { for _, pattern := range patterns { if strings.HasPrefix(pattern, "全部包含:") { vs := strings.Split(strings.TrimPrefix(pattern, "全部包含:"), "+") index := 0 for _, v := range vs { if strings.Contains(text, v) { index++ } } if index == len(vs) { log.Println(_id, "matchAnyPattern", pattern) return true } continue } if matched, _ := regexp.MatchString(pattern, text); matched { log.Println(_id, "matchAnyPattern", pattern) return true } } return false } // 全部匹配 func (r *Rule) matchAllPattern(text string, patterns []string) bool { count := 0 for _, pattern := range patterns { if matched, _ := regexp.MatchString(pattern, text); matched { count++ } } if count > 0 && count == len(patterns) { return true } return false }