wangchuanjin 1 hete
szülő
commit
4db57937fc
9 módosított fájl, 43 hozzáadás és 25 törlés
  1. 2 0
      README.md
  2. 7 3
      config.yaml
  3. BIN
      dataIdentify
  4. BIN
      extract
  5. 1 1
      extract.go
  6. 1 1
      main.go
  7. 17 7
      main_test.go
  8. 15 13
      service/rule.go
  9. BIN
      报价模式+中标联合体验证第三轮.xlsx

+ 2 - 0
README.md

@@ -1,3 +1,5 @@
+# 优先保证报价模式和中标联合体的准确率
+
 2+2
 2025/07/11 17:24:17 总共 794 报价模式不一致 26 中标联合体不一致 43
 1+2

+ 7 - 3
config.yaml

@@ -27,12 +27,14 @@ quoteMode:
         - "报价[方形模]式[::]总价"
         - "(成交|中标)总金额.{0,6}[::]"
       excludePatterns:
-        - "((?s)报价.{1,10}/)|单价|上浮|下浮|费率|折扣"
+        - "(报价.{1,10}/)|[.0-9]+%|单价|上浮|下浮|费率|折扣"
     - mode: "费率模式"
       tableV: "费率"
       tableKv:
         - k: "((投标|中标|成交)[\u4e00-\u9fa5]{0,8}[((]?费率[))]?)|投标报价系数|费率报价"
           v: "[0-9.]+%"
+      clearPatterns:
+        - "[上下]浮费率"
       patterns:
         - "(((投标|中标|成交)[\u4e00-\u9fa5]{0,8}[((]?费率[))]?)|投标报价系数|费率报价)[::][0-9.]+%"
         - "报价[方形模]式[::]费率"
@@ -43,7 +45,7 @@ quoteMode:
         - k: "(磋商|投标)报价.{0,6}[上下]浮率"
           v: "[0-9.]+%"
       patterns:
-        - "(统一|存款利率|中标|成交)[\u4e00-\u9fa5()()]{0,6}[上下]浮率为?[::]?[0-9.]+%"
+        - "(统一|存款利率|中标|成交|投标)[\u4e00-\u9fa5()()]{0,6}[上下]浮[费]?率为?[::]?[0-9.]+%"
         - "报价[方形模]式[::](上浮|下浮|折扣)"
         - "[上下]浮率报价[::]?[0-9.]+%"
         - "投标报价[::][上下]浮率"
@@ -60,9 +62,11 @@ quoteMode:
         - k: "单价"
           v: "[0-9.]+"
 bidCommonwealth:
+  clearPatterns:
+    - "(?s)第[^1一](中标|成交)[候侯]选人.+"
   # 白名单规则集合(确认是联合体中标)
   whitelistPatterns:
-    - "(((中标|成交)[^候选]{0,8})|(第一.{0,6}候选人))[::][\u4e00-\u9fa5]+[((]?(联合|主)体"
+    - "(((中标|成交)[^候选]{0,8})|(第一.{0,6}候选人))[::]([\u4e00-\u9fa5(())]+[((](联合|主)体|([\u4e00-\u9fa5(())]+[与和][\u4e00-\u9fa5(())]+)联合体)"
     - "联合体.{0,8}、.{2,20}联合体"
     - "([((]主[))].{2,30}[,,][((]成[))])"
     - "((牵头|成员)(人|羊|供应商|单位)|(投标|中标|成交)(联合体|成员))[::][\u4e00-\u9fa5]+"

BIN
dataIdentify


BIN
extract


+ 1 - 1
extract.go

@@ -15,7 +15,7 @@ import (
 	"time"
 )
 
-func main() {
+func main11() {
 	maxSize := flag.Int("c", 0, "")
 	poolSize := flag.Int("p", 5, "")
 	lastId := flag.String("id", "", "")

+ 1 - 1
main.go

@@ -12,7 +12,7 @@ import (
 	"os"
 )
 
-func main11() {
+func main() {
 	var logger *lumberjack.Logger
 	ctx := gctx.New()
 	g.Config().MustGet(ctx, "logger").Struct(&logger)

+ 17 - 7
main_test.go

@@ -6,13 +6,14 @@ import (
 	"github.com/xuri/excelize/v2"
 	"log"
 	"net/rpc"
+	"strings"
 	"sync"
 	"testing"
 )
 
 // 示例测试
 func TestRule(t *testing.T) {
-	Start("686964f0d5d8e4081f880f7c")
+	Start("6863d240d5d8e4081f770e9a")
 }
 
 /* 返回结果:
@@ -38,7 +39,7 @@ func TestRpc(t *testing.T) {
 // 总共 300 报价模式不一致 86 中标联合体不一致 2
 func TestCompare(t *testing.T) {
 	// 打开一个已存在的Excel文件。
-	of, err := excelize.OpenFile("./报价模式+中标联合体验证第轮.xlsx")
+	of, err := excelize.OpenFile("./报价模式+中标联合体验证第轮.xlsx")
 	if err != nil {
 		log.Fatalln(err)
 		return
@@ -87,7 +88,7 @@ func TestCompare(t *testing.T) {
 			}
 			lock.Lock()
 			result[row[0]] = map[string]interface{}{
-				"报价模式":  a,
+				"报价模式":   a,
 				"中标联合体": bv,
 			}
 			lock.Unlock()
@@ -104,6 +105,9 @@ func TestCompare(t *testing.T) {
 		if k == 0 {
 			continue
 		}
+		for i := 0; i < 8; i++ {
+			row = append(row, "")
+		}
 		bZOneFieldMap[row[4]]++
 		if row[4] != "" {
 			aaCount++
@@ -120,10 +124,16 @@ func TestCompare(t *testing.T) {
 			continue
 		}
 		if a != "" {
-			if a == row[4] {
+			if row[4] == "" {
 				aEq++
-				oneFieldEqMap[row[4]]++
-
+				oneFieldEqMap[a.(string)]++
+			} else {
+				for _, v := range strings.Split(row[4], "+") {
+					if v == a {
+						aEq++
+						oneFieldEqMap[v]++
+					}
+				}
 			}
 			aCount++
 			oneFieldMap[a.(string)]++
@@ -134,7 +144,7 @@ func TestCompare(t *testing.T) {
 			}
 			bCount++
 		}
-		if (a == "" || a == row[4]) && (b == "否" || b == row[6]) {
+		if (a == "" || row[4] == "" || strings.Contains(row[4], a.(string))) && (b == "否" || b == row[6]) {
 			continue
 		}
 		rowNum++

+ 15 - 13
service/rule.go

@@ -9,13 +9,6 @@ import (
 	"strings"
 )
 
-var (
-	bidCommonwealth_blacklistPatterns = g.Config().MustGet(gctx.New(), "bidCommonwealth.blacklistPatterns").Strings()
-	bidCommonwealth_whitelistPatterns = g.Config().MustGet(gctx.New(), "bidCommonwealth.whitelistPatterns").Strings()
-	quoteModeRules                    = g.Config().MustGet(gctx.New(), "quoteMode.rules").Maps()
-	quoteModeTableKReg                = g.Config().MustGet(gctx.New(), "quoteMode.tableK").String()
-)
-
 type Rule struct{}
 
 func (r *Rule) Execute(b *BidInfo) (string, int) {
@@ -29,7 +22,7 @@ func (r *Rule) Execute(b *BidInfo) (string, int) {
 	} else if b.Type == 2 {
 		bidCommonwealth = r.bidCommonwealth(b)
 	}
-	if quoteMode == QuoteMode_Whole && (b.Bidamount < g.Config().MustGet(gctx.New(), "quoteMode.minBidamount").Float64()) {
+	if quoteMode == QuoteMode_Whole && (b.Bidamount > 0 && b.Bidamount < g.Config().MustGet(gctx.New(), "quoteMode.minBidamount").Float64()) {
 		quoteMode = ""
 	}
 	log.Println(b.Id, "规则", "报价模式", quoteMode, "中标联合体", bidCommonwealth)
@@ -38,6 +31,7 @@ func (r *Rule) Execute(b *BidInfo) (string, int) {
 
 // 识别报价模式
 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()
@@ -48,7 +42,7 @@ func (r *Rule) quoteMode(b *BidInfo) (string, map[string]bool) {
 				mustTableKvMap := map[int]bool{}
 				for k, v := range row {
 					if tableV := vv["tableV"].String(); tableV != "" {
-						matchedK, _ := regexp.MatchString(quoteModeTableKReg, k)
+						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)
@@ -107,11 +101,15 @@ func (r *Rule) quoteMode(b *BidInfo) (string, map[string]bool) {
 	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, b.Detail, excludePatterns) {
+		if len(excludePatterns) > 0 && !r.matchAnyPattern(b.Id, detail, excludePatterns) {
 			return modeName, nil
 		}
-		lines := strings.Split(b.Detail, "\n")
+		lines := strings.Split(detail, "\n")
 		for _, lineVal := range lines {
 			if r.matchAnyPattern(b.Id, lineVal, vv["patterns"].Strings()) {
 				return modeName, nil
@@ -124,10 +122,14 @@ func (r *Rule) quoteMode(b *BidInfo) (string, map[string]bool) {
 // 识别中标联合体
 func (r *Rule) bidCommonwealth(b *BidInfo) int {
 	// Step 1: 排除黑名单
-	if r.matchAnyPattern(b.Id, b.Detail, bidCommonwealth_blacklistPatterns) {
+	if r.matchAnyPattern(b.Id, b.Detail, g.Config().MustGet(gctx.New(), "bidCommonwealth.blacklistPatterns").Strings()) {
 		return -1
 	}
-	if r.matchAnyPattern(b.Id, b.Detail, bidCommonwealth_whitelistPatterns) {
+	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

BIN
报价模式+中标联合体验证第三轮.xlsx