rule.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. "github.com/gogf/gf/v2/util/gconv"
  7. "log"
  8. "regexp"
  9. "strings"
  10. )
  11. var (
  12. clearPatterns = g.Config().MustGet(gctx.New(), "clearPatterns").Strings()
  13. bidCommonwealth_blacklistPatterns = g.Config().MustGet(gctx.New(), "bidCommonwealth.blacklistPatterns").Strings()
  14. bidCommonwealth_whitelistPatterns = g.Config().MustGet(gctx.New(), "bidCommonwealth.whitelistPatterns").Strings()
  15. bidCommonwealth_modelPatterns = g.Config().MustGet(gctx.New(), "bidCommonwealth.modelPatterns").Strings()
  16. bidCommonwealth_firstWinnerOrder = g.Config().MustGet(gctx.New(), "bidCommonwealth.firstWinnerOrder").String()
  17. quoteModeRules = g.Config().MustGet(gctx.New(), "quoteMode.rules").Maps()
  18. quoteMode_modelPatterns = g.Config().MustGet(gctx.New(), "quoteMode.modelPatterns").Strings()
  19. allQuoteMode = map[string]bool{}
  20. showOnlyOnce = [][]string{}
  21. )
  22. func init() {
  23. for _, v := range g.Config().MustGet(gctx.New(), "bidCommonwealth.showOnlyOnce").Array() {
  24. showOnlyOnce = append(showOnlyOnce, gconv.Strings(v))
  25. }
  26. for _, v := range quoteModeRules {
  27. vv := gvar.New(v).MapStrVar()
  28. allQuoteMode[vv["mode"].String()] = true
  29. }
  30. }
  31. type Rule struct{}
  32. // 判断是否是联合体中标
  33. func (r *Rule) Execute(b *BidInfo) (bool, string, int, map[string]interface{}) {
  34. bc := r.bidCommonwealth(b)
  35. quoteMode := r.quoteMode(b)
  36. if bc == -2 && quoteMode == "大模型识别" {
  37. _, quoteMode, bc, _ = (&Model{}).Do(b, 2)
  38. } else if bc == -2 {
  39. _, _, bc, _ = (&Model{}).Do(b, 3)
  40. } else if quoteMode == "大模型识别" {
  41. _, quoteMode, _, _ = (&Model{}).Do(b, 1)
  42. }
  43. if (quoteMode == "" || quoteMode == "无法识别") && b.Bidamount > 0 {
  44. quoteMode = "整体报价模式"
  45. }
  46. log.Println(b.Id, "规则", "报价模式", quoteMode, "中标联合体", bc)
  47. return true, quoteMode, bc, nil
  48. }
  49. // 识别中标联合体
  50. func (r *Rule) quoteMode(b *BidInfo) string {
  51. for _, line := range strings.Split(b.Detail, "\n") {
  52. for _, v := range quoteModeRules {
  53. vv := gvar.New(v).MapStrVar()
  54. if r.matchAnyPattern(line, vv["patterns"].Strings()) {
  55. return vv["mode"].String()
  56. }
  57. }
  58. }
  59. if r.matchAnyPattern(b.Detail, quoteMode_modelPatterns) {
  60. return "大模型识别"
  61. }
  62. return ""
  63. }
  64. // 识别中标联合体
  65. func (r *Rule) bidCommonwealth(b *BidInfo) int {
  66. if len(b.WinnerOrder) > 0 {
  67. if regexp.MustCompile(bidCommonwealth_firstWinnerOrder).MatchString(b.WinnerOrder[0]) {
  68. return 1
  69. }
  70. return -1
  71. }
  72. for _, v := range strings.Split(b.KvText, "\n") {
  73. if r.matchAnyPattern(v, bidCommonwealth_whitelistPatterns) {
  74. return 1
  75. }
  76. }
  77. v := b.Detail
  78. // Step 1: 排除黑名单
  79. if r.matchAnyPattern(v, bidCommonwealth_blacklistPatterns) {
  80. return -1
  81. }
  82. if r.matchOnlyOnce(v) {
  83. return 1
  84. }
  85. // Step 2: 精准匹配白名单
  86. if r.matchAnyPattern(v, bidCommonwealth_whitelistPatterns) {
  87. return 1
  88. }
  89. // Step 3: 检查“中标”附近是否有“联合体”
  90. index := strings.Index(v, "中标")
  91. if index != -1 {
  92. start := max(0, index-50)
  93. end := min(len(v), index+50)
  94. contextAroundWin := v[start:end]
  95. if strings.Contains(contextAroundWin, "联合体") {
  96. return 1
  97. }
  98. }
  99. if r.matchAnyPattern(v, bidCommonwealth_modelPatterns) {
  100. return -2
  101. }
  102. return -1
  103. }
  104. // 匹配任意模式
  105. func (r *Rule) matchAnyPattern(text string, patterns []string) bool {
  106. for _, pattern := range patterns {
  107. if strings.HasPrefix(pattern, "全部包含:") {
  108. vs := strings.Split(strings.TrimPrefix(pattern, "全部包含:"), "+")
  109. index := 0
  110. for _, v := range vs {
  111. if strings.Contains(text, v) {
  112. index++
  113. }
  114. }
  115. if index == len(vs) {
  116. log.Println(pattern)
  117. return true
  118. }
  119. continue
  120. }
  121. if matched, _ := regexp.MatchString(pattern, text); matched {
  122. log.Println(pattern)
  123. return true
  124. }
  125. }
  126. return false
  127. }
  128. func (r *Rule) matchOnlyOnce(text string) bool {
  129. for _, v := range showOnlyOnce {
  130. count := 0
  131. for _, vv := range v {
  132. if len(regexp.MustCompile(vv).FindAllString(text, -1)) != 1 {
  133. break
  134. }
  135. count++
  136. }
  137. if count > 0 && count == len(v) {
  138. return true
  139. }
  140. }
  141. return false
  142. }