rule.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package service
  2. import (
  3. "github.com/gogf/gf/v2/container/gvar"
  4. "github.com/gogf/gf/v2/frame/g"
  5. "github.com/gogf/gf/v2/os/gctx"
  6. "log"
  7. "regexp"
  8. "strings"
  9. )
  10. var (
  11. bidCommonwealth_blacklistPatterns = g.Config().MustGet(gctx.New(), "bidCommonwealth.blacklistPatterns").Strings()
  12. bidCommonwealth_whitelistPatterns = g.Config().MustGet(gctx.New(), "bidCommonwealth.whitelistPatterns").Strings()
  13. quoteModeRules = g.Config().MustGet(gctx.New(), "quoteMode.rules").Maps()
  14. quoteModeTableKReg = g.Config().MustGet(gctx.New(), "quoteMode.tableK").String()
  15. )
  16. type Rule struct{}
  17. func (r *Rule) Execute(b *BidInfo) (string, int) {
  18. var bidCommonwealth int
  19. var quoteMode string
  20. if b.Type == 0 {
  21. bidCommonwealth = r.bidCommonwealth(b)
  22. quoteMode, _ = r.quoteMode(b)
  23. } else if b.Type == 1 {
  24. quoteMode, _ = r.quoteMode(b)
  25. } else if b.Type == 2 {
  26. bidCommonwealth = r.bidCommonwealth(b)
  27. }
  28. if quoteMode == QuoteMode_Whole && (b.Bidamount < g.Config().MustGet(gctx.New(), "quoteMode.minBidamount").Float64()) {
  29. quoteMode = ""
  30. }
  31. log.Println(b.Id, "规则", "报价模式", quoteMode, "中标联合体", bidCommonwealth)
  32. return quoteMode, bidCommonwealth
  33. }
  34. // 识别报价模式
  35. func (r *Rule) quoteMode(b *BidInfo) (string, map[string]bool) {
  36. for _, v := range quoteModeRules {
  37. vv := gvar.New(v).MapStrVar()
  38. mustTableKv := vv["mustTableKv"].Maps()
  39. modeName := vv["mode"].String()
  40. for _, table := range b.TableKv {
  41. array := []string{}
  42. for _, row := range table {
  43. mustTableKvMap := map[int]bool{}
  44. for k, v := range row {
  45. if tableV := vv["tableV"].String(); tableV != "" {
  46. matchedK, _ := regexp.MatchString(quoteModeTableKReg, k)
  47. if !matchedK {
  48. if tableK := vv["tableK"].String(); tableK != "" {
  49. matchedK, _ = regexp.MatchString(tableK, k)
  50. }
  51. }
  52. matchedV, _ := regexp.MatchString(tableV, v)
  53. if matchedK && matchedV {
  54. log.Println(b.Id, "tableKv", k, v)
  55. return modeName, nil
  56. }
  57. }
  58. //
  59. for _, vv := range vv["tableKv"].Maps() {
  60. vvs := gvar.New(vv).MapStrVar()
  61. tableK := vvs["k"].String()
  62. tableV := vvs["v"].String()
  63. if tableK == "" || tableV == "" {
  64. continue
  65. }
  66. matchedK, _ := regexp.MatchString(tableK, k)
  67. matchedV, _ := regexp.MatchString(tableV, v)
  68. if matchedK && matchedV {
  69. log.Println(b.Id, "tableKv", k, v)
  70. return modeName, nil
  71. }
  72. }
  73. //
  74. for kk, vv := range mustTableKv {
  75. vvs := gvar.New(vv).MapStrVar()
  76. tableK := vvs["k"].String()
  77. tableV := vvs["v"].String()
  78. if tableK == "" || tableV == "" {
  79. continue
  80. }
  81. matchedK, _ := regexp.MatchString(tableK, k)
  82. matchedV, _ := regexp.MatchString(tableV, v)
  83. if matchedK && matchedV {
  84. array = append(array, k+":"+v)
  85. mustTableKvMap[kk] = true
  86. break
  87. }
  88. }
  89. }
  90. for kk, _ := range mustTableKv {
  91. if !mustTableKvMap[kk] {
  92. break
  93. }
  94. if kk == len(mustTableKv)-1 {
  95. log.Println(b.Id, "mustTableKv", strings.Join(array, " "))
  96. return modeName, nil
  97. }
  98. }
  99. }
  100. }
  101. }
  102. for _, v := range quoteModeRules {
  103. vv := gvar.New(v).MapStrVar()
  104. modeName := vv["mode"].String()
  105. excludePatterns := vv["excludePatterns"].Strings()
  106. if len(excludePatterns) > 0 && !r.matchAnyPattern(b.Id, b.Detail, excludePatterns) {
  107. return modeName, nil
  108. }
  109. lines := strings.Split(b.Detail, "\n")
  110. for _, lineVal := range lines {
  111. if r.matchAnyPattern(b.Id, lineVal, vv["patterns"].Strings()) {
  112. return modeName, nil
  113. }
  114. }
  115. }
  116. return "", nil
  117. }
  118. // 识别中标联合体
  119. func (r *Rule) bidCommonwealth(b *BidInfo) int {
  120. // Step 1: 排除黑名单
  121. if r.matchAnyPattern(b.Id, b.Detail, bidCommonwealth_blacklistPatterns) {
  122. return -1
  123. }
  124. if r.matchAnyPattern(b.Id, b.Detail, bidCommonwealth_whitelistPatterns) {
  125. return 1
  126. }
  127. return -1
  128. }
  129. // 匹配任意模式
  130. func (r *Rule) matchAnyPattern(_id string, text string, patterns []string) bool {
  131. for _, pattern := range patterns {
  132. if strings.HasPrefix(pattern, "全部包含:") {
  133. vs := strings.Split(strings.TrimPrefix(pattern, "全部包含:"), "+")
  134. index := 0
  135. for _, v := range vs {
  136. if strings.Contains(text, v) {
  137. index++
  138. }
  139. }
  140. if index == len(vs) {
  141. log.Println(_id, "matchAnyPattern", pattern)
  142. return true
  143. }
  144. continue
  145. }
  146. if matched, _ := regexp.MatchString(pattern, text); matched {
  147. log.Println(_id, "matchAnyPattern", pattern)
  148. return true
  149. }
  150. }
  151. return false
  152. }
  153. // 全部匹配
  154. func (r *Rule) matchAllPattern(text string, patterns []string) bool {
  155. count := 0
  156. for _, pattern := range patterns {
  157. if matched, _ := regexp.MatchString(pattern, text); matched {
  158. count++
  159. }
  160. }
  161. if count > 0 && count == len(patterns) {
  162. return true
  163. }
  164. return false
  165. }