Ver Fonte

备份~主要修改两点
一、单元格解析~长度过长截取3W
二、找冒号KV,正则划分过慢~新增过多冒号过滤原则

zhengkun há 2 anos atrás
pai
commit
03f3198088

+ 6 - 5
extcity/src/config.json

@@ -1,17 +1,18 @@
 {
+   "port": ":9991",
    "ext_mgodb": {
-     "addr": "172.17.145.163:27083,172.17.4.187:27082",
+     "addr": "127.0.0.1:27017",
      "db": "mixdata",
      "ext_coll": "address_new_2020",
-     "check_coll": "address_jy_2021",
+     "check_coll": "address_jy_2022",
      "pool": 10,
-     "user": "zhengkun",
-     "password": "zk@123123"
+     "user": "",
+     "password": ""
    },
   "save_mgodb": {
     "addr": "120.0.0.1:27017",
     "db": "zhengkun",
-    "coll": "ccccccccddddddd",
+    "coll": "xxxxxx",
     "pool": 10,
     "user": "",
     "password": ""

+ 202 - 31
extcity/src/ext/extcity.go

@@ -3,6 +3,7 @@ package ext
 import (
 	log "github.com/donnie4w/go-logger/logger"
 	qu "qfw/util"
+	"regexp"
 	"sync"
 )
 type Job struct {
@@ -13,6 +14,10 @@ type Job struct {
 	SimCityScore      map[string]float64                //简称city得分
 	SimDistrictScore  map[string]float64                //简称district得分
 }
+var AgencyReg = []*regexp.Regexp{
+	regexp.MustCompile("(?s)(代理(机构|人|单位|公司)|中标供应商).{0,30}"),
+	regexp.MustCompile(".{2,15}((招标)?代理|咨询|政府采购)"),
+}
 //支持排序的map
 type SortMap struct {
 	Index map[string]int
@@ -77,7 +82,7 @@ func removeslice(slice []string, elem interface{}) []string {
 
 
 //抽取城市
-func (e *ExtractTask) NewExtractCity(data map[string]interface{})( map[string]interface{}) {
+func (e *ExtractTask) NewExtractCityField(data map[string]interface{})( map[string]interface{}) {
 	defer qu.Catch()
 	//初始化
 	j := &Job{
@@ -91,25 +96,84 @@ func (e *ExtractTask) NewExtractCity(data map[string]interface{})( map[string]in
 	pscore := make(map[string]float64)
 	cscore := make(map[string]float64)
 	dscore := make(map[string]float64)
-
 	sm := NewSortMap()
 	for k,v := range data{
 		sm.AddKey(k, qu.ObjToString(v))
 	}
 	e.NewGetCityByOthers(j, sm, &pscore, &cscore, &dscore)
-	//qu.Debug("全称打分后结果---", j.FullAreaScore, j.FullCityScore, j.FullDistrictScore)
-	//qu.Debug("简称打分后结果---", j.SimAreaScore, j.SimCityScore, j.SimDistrictScore)
-
-	//全称简称得分合并
-	MergeFullSimScore(j)
-	//qu.Debug("全称简称合并后---", j.FullAreaScore, j.FullCityScore, j.FullDistrictScore)
-	//qu.Debug("pcd=====", pscore, cscore, dscore)
-
-	//合并区简称匹配的pcd
+	MergeFullSimScore(j)//全称简称得分合并
 	MergeScores(j, &pscore, &cscore, &dscore)
-	//qu.Debug("合并区简称打分后结果---", j.FullAreaScore, j.FullCityScore, j.FullDistrictScore)
-
 
+	finishP := HighestScoreArr(j.FullAreaScore) //获取最高分的省
+	e.RemoveCD(finishP, j)
+	finishC := HighestScoreArr(j.FullCityScore)
+	finishD := HighestScoreArr(j.FullDistrictScore)
+	arearesult := ""
+	cityresult := ""
+	districtresult := ""
+	tmpcity := []string{}
+	if len(finishP) == 1 { //最高分一个
+		arearesult = finishP[0] //抽取结果直接赋值
+		cityresult, tmpcity = NewGetCity(arearesult, cityresult, e, finishC, tmpcity)
+		cityresult, districtresult = NewGetDistrict(arearesult, cityresult, districtresult, e, finishD, tmpcity)
+	} else if len(finishP) > 1 { //province最高分多个
+		if len(finishC) == 1 {
+			cityresult = finishC[0]
+			if cfMap := e.CityFullMap[cityresult]; cfMap != nil {
+				arearesult = cfMap.P.Brief
+				tmpcity = append(tmpcity, cityresult)
+				cityresult, districtresult = NewGetDistrict(arearesult, cityresult, districtresult, e, finishD, tmpcity)
+			}
+		} else { //对应的city有多个(多个province和city)
+			arearesult = "全国"
+		}
+	}
+	if cityresult != "" && cityresult == districtresult {
+		districtresult = ""
+	}
+	//直辖市
+	if arearesult == "北京" {
+		cityresult = "北京市"
+		if districtresult == "北京朝阳" { //特殊情况(北京朝阳中西医结合急诊抢救中心:5a84079740d2d9bbe88bad90)
+			districtresult = "朝阳区"
+		}
+	} else if arearesult == "天津" {
+		cityresult = "天津市"
+	} else if arearesult == "上海" {
+		cityresult = "上海市"
+	} else if arearesult == "重庆" {
+		cityresult = "重庆市"
+	}
+	if arearesult == "" {
+		arearesult = "全国"
+	}
+	resultTmp := map[string]interface{}{}
+	if arearesult!="" {
+		resultTmp["area"] = arearesult
+	}
+	if cityresult!="" {
+		resultTmp["city"] = cityresult
+	}
+	if districtresult!="" {
+		resultTmp["district"] = districtresult
+	}
+	return resultTmp
+}
+//单字段正文
+func (e *ExtractTask) NewExtractCityDetail(data map[string]interface{})( map[string]interface{}) {
+	defer qu.Catch()
+	//初始化
+	j := &Job{
+		map[string]float64{},
+		map[string]float64{},
+		map[string]float64{},
+		map[string]float64{},
+		map[string]float64{},
+		map[string]float64{},
+	}
+	detail := qu.ObjToString(data["detail"])
+	e.NewGetCityByDetail(j,detail)
+	MergeFullSimScore(j) //合并detail的全简称
 	finishP := HighestScoreArr(j.FullAreaScore) //获取最高分的省
 	e.RemoveCD(finishP, j)                      //将city中所属干扰项省的city去除,同时去除district.5d2bd4aba5cb26b9b769d18e
 	//获取结果
@@ -138,7 +202,6 @@ func (e *ExtractTask) NewExtractCity(data map[string]interface{})( map[string]in
 	if cityresult != "" && cityresult == districtresult {
 		districtresult = ""
 	}
-	//qu.Debug("结果===", arearesult, "--", cityresult, "--", districtresult)
 	//直辖市
 	if arearesult == "北京" {
 		cityresult = "北京市"
@@ -154,13 +217,7 @@ func (e *ExtractTask) NewExtractCity(data map[string]interface{})( map[string]in
 	}
 	if arearesult == "" {
 		arearesult = "全国"
-	} /* else if cityresult == "" {
-		if pbMap := e.ProvinceBriefMap[arearesult]; pbMap != nil {
-			cityresult = pbMap.Cap
-			resulttmp["defaultpcap"] = true
-		}
-	}*/
-	//qu.Debug("结果2===", arearesult, "--", cityresult, "--", districtresult)
+	}
 	resultTmp := map[string]interface{}{}
 	if arearesult!="" {
 		resultTmp["area"] = arearesult
@@ -174,6 +231,125 @@ func (e *ExtractTask) NewExtractCity(data map[string]interface{})( map[string]in
 	return resultTmp
 }
 
+
+
+
+//不同情况的抽取方法
+func (e *ExtractTask) NewGetCityByDetail(j *Job,detail string) {
+	repeatP_full := map[string]bool{}
+	repeatC_full := map[string]bool{}
+	repeatD_full := map[string]bool{}
+	repeatP_sim := map[string]bool{}
+	repeatC_sim := map[string]bool{}
+	repeatD_sim := map[string]bool{}
+	for _, reg := range AgencyReg {
+		detail = reg.ReplaceAllString(detail, "")
+	}
+	for _, text := range e.Seg_SV.Cut(detail, true) {
+		if len([]rune(text)) > 1 {
+			//全称匹配
+			for pos_full, trie_full := range e.Trie_Fulls {
+				if trie_full.Get(text) {
+					if pos_full == 0 { //省全称
+						if tmpPbrief := e.ProvinceMap[text]; tmpPbrief != "" && !repeatP_full[tmpPbrief] { //取简称
+							PCDScore(j, "province", tmpPbrief, 1, true)
+							repeatP_full[tmpPbrief] = true
+							break
+						}
+					} else if pos_full == 1 { //市全称
+						if cfMap := e.CityFullMap[text]; cfMap != nil {
+							if !repeatP_full[cfMap.P.Brief] {
+								PCDScore(j, "province", cfMap.P.Brief, 1, true)
+								repeatP_full[cfMap.P.Brief] = true
+							}
+							if !repeatC_full[cfMap.Name] {
+								PCDScore(j, "city", cfMap.Name, 1, true)
+								repeatC_full[cfMap.Name] = true
+							}
+							break
+						}
+					} else if pos_full == 2 { //区全称
+						citys := e.NewDistrictCityMap[text]
+						if len(citys) > 0 {
+							if !repeatD_full[text] {
+								PCDScore(j, "district", text, 1, true)
+								repeatD_full[text] = true
+							}
+							for _, c := range citys {
+								if !repeatC_full[c.Name] {
+									PCDScore(j, "city", c.Name, 1, true)
+									repeatC_full[c.Name] = true
+								}
+								if !repeatP_full[c.P.Brief] {
+									PCDScore(j, "province", c.P.Brief, 1, true)
+									repeatP_full[c.P.Brief] = true
+								}
+							}
+							break
+						}
+					} else if pos_full == 3 { //街道全称
+						districts := e.NewStreetDistrictMap[text]
+						if len(districts) == 1 {
+							DealMultipleDistrict(e, j, districts, 1, "", &repeatP_full, &repeatC_full, &repeatD_full)
+						}
+					} else if pos_full == 4 { //居委会全称
+						districts := e.CommunityDistrictMap[text]
+						if len(districts) == 1 {
+							DealMultipleDistrict(e, j, districts, 1, "", &repeatP_full, &repeatC_full, &repeatD_full)
+						}
+					}
+				}
+			}
+			//qu.Debug("detail 全称---", j.AreaScore, j.CityScore, j.DistrictScore)
+			//简称匹配
+			for pos_sim, trie_sim := range e.Trie_Sims {
+				if trie_sim.Get(text) {
+					if pos_sim == 0 && !repeatP_sim[text] { //省简称
+						PCDScore(j, "province", text, 1, false)
+						repeatP_sim[text] = true
+						break
+					} else if pos_sim == 1 { //市简称
+						if cbMap := e.CityBriefMap[text]; cbMap != nil {
+							if !repeatP_sim[cbMap.P.Brief] {
+								PCDScore(j, "province", cbMap.P.Brief, 1, false)
+								repeatP_sim[cbMap.P.Brief] = true
+							}
+							if !repeatC_sim[cbMap.Name] {
+								PCDScore(j, "city", cbMap.Name, 1, false)
+								repeatC_sim[cbMap.Name] = true
+							}
+							break
+						}
+					} else if pos_sim == 2 { //区简称
+						dfull_citys := e.NewDistrictSimAndAll[text]
+						if len(dfull_citys) == 1 {
+							for _, dfull_city := range dfull_citys {
+								for dfull, ctmp := range dfull_city { //dfull:简称对应的全称
+									if !repeatD_sim[dfull] {
+										PCDScore(j, "district", dfull, 1, false)
+										repeatD_sim[dfull] = true
+									}
+									if ctmp == nil {
+										continue
+									}
+									if !repeatC_sim[ctmp.Name] {
+										PCDScore(j, "city", ctmp.Name, 1, false)
+										repeatC_sim[ctmp.Name] = true
+									}
+									if !repeatP_sim[ctmp.P.Brief] {
+										PCDScore(j, "province", ctmp.P.Brief, 1, false)
+										repeatP_sim[ctmp.P.Brief] = true
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+			//qu.Debug("detail 简称---", j.AreaScore, j.CityScore, j.DistrictScore)
+		}
+	}
+}
 func (e *ExtractTask) NewGetCityByOthers(j *Job, sm *SortMap, pscore, cscore, dscore *map[string]float64) {
 	/*
 		1.对字段进行分词
@@ -367,6 +543,11 @@ func (e *ExtractTask) NewGetCityByOthers(j *Job, sm *SortMap, pscore, cscore, ds
 		}
 	}
 }
+
+
+
+
+
 func MergeScores(j *Job, pscore, cscore, dscore *map[string]float64) {
 	if len(j.FullAreaScore) > 0 {
 		for pt, ps := range *pscore {
@@ -424,7 +605,6 @@ func NewGetCity(area, city string, e *ExtractTask, finishC, tmpcity []string) (s
 	}
 	return city, tmpcity
 }
-
 func NewGetDistrict(area, city, district string, e *ExtractTask, finishD, tmpcity []string) (string, string) {
 	for _, d := range finishD { //取最高分与province匹配的district
 		citys := e.NewDistrictCityMap[d]
@@ -453,8 +633,6 @@ func NewGetDistrict(area, city, district string, e *ExtractTask, finishD, tmpcit
 	}
 	return city, district
 }
-
-
 func HighestScoreArr(m map[string]float64) []string {
 	result := make(map[float64][]string)
 	tmpscore := 0.0
@@ -474,8 +652,6 @@ func HighestScoreArr(m map[string]float64) []string {
 	}
 	return result[tmpscore]
 }
-
-
 func (e *ExtractTask) RemoveCD(finishP []string, j *Job) {
 	if len(j.FullDistrictScore) > 0 {
 		for d, _ := range j.FullDistrictScore {
@@ -524,9 +700,6 @@ func (e *ExtractTask) RemoveCD(finishP []string, j *Job) {
 	}
 
 }
-
-
-
 //计算province,city,district得分
 func PCDScore(j *Job, stype, text string, score float64, isfull bool) {
 	defer qu.Catch()
@@ -561,8 +734,6 @@ func PCDScore(j *Job, stype, text string, score float64, isfull bool) {
 		}
 	}
 }
-
-
 //街道、居委会对应多地市处理
 func DealMultipleDistrict(e *ExtractTask, j *Job, districts []*District, score float64, pbrief string, repeatP, repeatC, repeatD *map[string]bool) {
 	if len(districts) == 1 {

+ 39 - 4
extcity/src/main.go

@@ -1,14 +1,18 @@
 package main
 
 import (
+	"encoding/json"
 	"ext"
 	log "github.com/donnie4w/go-logger/logger"
+	"net/http"
 	qu "qfw/util"
+	"sync"
+	"time"
 	ul "util"
 )
 
 var e *ext.ExtractTask
-
+var datalock sync.Mutex
 func init()  {
 	log.Debug("配置文件准备完毕...")
 	ul.InitExt()
@@ -20,9 +24,40 @@ func main()  {
 	log.Debug("城市抽取加载完毕...")
 	ext.InitCheckCity()  	//初始化-校验城市
 
-	fromSourceDataExtCity()
+	//调试
+	ext_res := map[string]interface{}{}
+	ext_res = e.NewExtractCityDetail(map[string]interface{}{
+		"detail":"东风路街道",
+	})
+	log.Debug(ext_res)
+
+	//初始化接口
+	initNetwork()
+	log.Debug("开始监听~",ul.Port)
+	http.ListenAndServe(ul.Port, nil)
+	time.Sleep(99999*time.Hour)
+}
+
+//接口方法
+func initNetwork()  {
+	http.HandleFunc("/getcity", func(w http.ResponseWriter, r *http.Request) {
+		datalock.Lock()
+		detail := r.FormValue("detail")
+		//处理detail
+		ext_res := map[string]interface{}{}
+		if detail!="" {
+			ext_res = e.NewExtractCityDetail(map[string]interface{}{
+				"detail":detail,
+			})
+		}
+		res,_:=json.Marshal(ext_res)
+		w.Write(res)
+		datalock.Unlock()
+	})
 }
-//抽取城市-源表-
+
+
+//抽取城市-源表-采用表格数据
 func fromSourceDataExtCity()  {
 	q := map[string]interface{}{}
 	sess := ul.SaveMgo.GetMgoConn()
@@ -39,7 +74,7 @@ func fromSourceDataExtCity()  {
 			source_field[k] = qu.ObjToString(tmp[k])
 		}
 		if len(source_field)>0 {
-			ext_res := e.NewExtractCity(source_field)
+			ext_res := e.NewExtractCityField(source_field)
 			isok++
 			ul.SaveMgo.UpdateByStringId(ul.SaveColl,tmpid, map[string]interface{}{
 				"$set": ext_res,

+ 24 - 0
extcity/src/mark

@@ -0,0 +1,24 @@
+{
+   "port": ":9991",
+   "ext_mgodb": {
+     "addr": "172.17.145.163:27083,172.17.4.187:27082",
+     "db": "mixdata",
+     "ext_coll": "address_new_2020",
+     "check_coll": "address_jy_2022",
+     "pool": 10,
+     "user": "zhengkun",
+     "password": "zk@123123"
+   },
+  "save_mgodb": {
+    "addr": "120.0.0.1:27017",
+    "db": "zhengkun",
+    "coll": "zktest_data_new_city",
+    "pool": 10,
+    "user": "",
+    "password": ""
+  },
+  "source_field": {
+    "authority": 1,
+    "company_address": 1
+  }
+}

+ 4 - 2
extcity/src/util/init.go

@@ -10,6 +10,7 @@ var (
 	ExtMgo,SaveMgo  *MongodbSim //抽取初始化-相关
 	ExtColl,CheckColl,SaveColl		string
 	SF 	map[string]interface{}
+	Port			string
 )
 
 
@@ -20,6 +21,7 @@ func InitExt() {
 		log.Fatalln("init config err")
 	}
 	SF = *qu.ObjToMap(Sysconfig["source_field"])
+	Port = qu.ObjToString(Sysconfig["port"])
 	initMgo()
 }
 func initMgo () {
@@ -42,8 +44,8 @@ func initMgo () {
 		MongodbAddr: extconf["addr"].(string),
 		DbName:      extconf["db"].(string),
 		Size:        qu.IntAllDef(extconf["pool"], 5),
-		UserName: 	saveconf["user"].(string),
-		PassWord: 	saveconf["password"].(string),
+		UserName: 	extconf["user"].(string),
+		PassWord: 	extconf["password"].(string),
 	}
 	ExtMgo.InitPool()
 }

+ 7 - 35
src/config.json

@@ -5,25 +5,9 @@
     "dbname": "extract_local",
     "dbname_addrs": "mixdata",
     "dbname_addrs_c": "address_new_2020",
-    "redis": "qyk_redis=192.168.3.207:6379",
-    "elasticsearch": "http://127.0.0.1:9800",
-    "elasticsearch_index": "winner_enterprise_tmp",
-    "elasticsearch_type": "winnerent",
-    "elasticsearch_db": "winner_enterprise",
-    "elasticsearch_buyer_index": "buyer_enterprise_tmp",
-    "elasticsearch_buyer_type": "buyerent",
-    "elasticsearch_buyer_db": "buyer_enterprise",
-    "elasticsearch_agency_index": "agency_enterprise_tmp",
-    "elasticsearch_agency_type": "agencyent",
-    "elasticsearch_agency_db": "agency_enterprise",
-    "redis_qyk": "qyk_redis",
-    "redis_winner_db": "1",
-    "redis_buyer_db": "2",
-    "redis_agency_db": "3",
-    "elasticPoolSize": 1,
     "mergetable": "projectset",
     "mergetablealias": "projectset_v1",
- 	"ffield": true,
+    "ffield": true,
     "saveresult": false,
     "fieldsfind": false,
     "qualityaudit": false,
@@ -32,26 +16,14 @@
     "iscltlog": false,
     "brandgoods": false,
     "pricenumber":true,
+    "udpport": "6601",
     "udptaskid": "60b493c2e138234cb4adb640",
     "nextNode": [],
-    "udpport": "6601",
-    "udpmachine": {
-        "addr" : "127.0.0.1",
-        "port" : 6601,
-        "stype" : "extract_1",
-        "isuse" : 1
-    },
     "esconfig": {
-        "available": false,
-        "AccessID": "",
-        "AccessSecret": "",
+        "available": true,
+        "AccessID": "LTAI4G5x9aoZx8dDamQ7vfZi",
+        "AccessSecret": "Bk98FsbPYXcJe72n1bG3Ssf73acuNh",
         "ZoneIds": [
-            {
-                "zoneid": "cn-beijing-f",
-                "LaunchTemplateId4": "lt-2zejb8ayql48hn0hcjpy",
-                "LaunchTemplateId8": "lt-2zegx87hj07phcdtoh61",
-                "vswitchid": "vsw-2zei6snkgmqxcnnx6g04d"
-            },
             {
                 "zoneid": "cn-beijing-g",
                 "LaunchTemplateId4": "lt-2ze5ktfgopayi48ok0hu",
@@ -60,7 +32,7 @@
             },
             {
                 "zoneid": "cn-beijing-h",
-                "LaunchTemplateId4": "lt-2ze5ir54gy4ui8okr71f",
+                "LaunchTemplateId4": "lt-2ze1h0akjvi4sdemm7cj",
                 "LaunchTemplateId8": "lt-2ze5fzxwgt8jcqczvmjy",
                 "vswitchid": "vsw-2ze1n1k3mo3fv2irsfdps"
             }
@@ -72,4 +44,4 @@
     "api": "http://10.171.112.160:19281/_send/_mail",
     "deleteInstanceTimeHour": 1,
     "jsondata_extweight": 1
-} 
+}

+ 1 - 0
src/jy/cluster/aliecs.go

@@ -156,6 +156,7 @@ func DeleteInstance(InstanceId string) {
 func ModifyInstanceAutoReleaseTime(InstanceId string, hours int) {
 	res := GET("ModifyInstanceAutoReleaseTime", [][]string{
 		[]string{"InstanceId", InstanceId},
+		[]string{"RegionId","cn-beijing"},
 		[]string{"AutoReleaseTime", time.Now().Add(time.Duration(hours) * time.Hour).UTC().Format("2006-01-02T15:04:05Z")},
 	})
 	log.Println("ModifyInstanceAutoReleaseTime", res)

+ 202 - 192
src/jy/extract/extract.go

@@ -26,16 +26,16 @@ import (
 
 var (
 	lock, lockrule, lockclear, locktag, blocktag sync.RWMutex
-    JYUrl = "https://www.jianyu360.com/article/content/%s.html"
-	cut           = ju.NewCut()                          //获取正文并清理
-	ExtLogs       map[*TaskInfo][]map[string]interface{} //抽取日志
-	TaskList      map[string]*ExtractTask                //任务列表
-	ClearTaskList map[string]*ClearTask                  //清理任务列表
-	saveLimit     = 100                                  //抽取日志批量保存
-	PageSize      = 5000                                 //查询分页
-	Fields        = `{"jyfb_data":1,"title":1,"summary":1,"detail":1,"contenthtml":1,"site":1,"spidercode":1,"toptype":1,"subtype":1,"bidstatus":1,"area":1,"city":1,"comeintime":1,"publishtime":1,"sensitive":1,"projectinfo":1,"jsondata":1,"href":1,"infoformat":1,"attach_text":1,"dataging":1,"review_experts":1,"purchasing":1}`
+	JYUrl                                        = "https://www.jianyu360.com/article/content/%s.html"
+	cut                                          = ju.NewCut()                          //获取正文并清理
+	ExtLogs                                      map[*TaskInfo][]map[string]interface{} //抽取日志
+	TaskList                                     map[string]*ExtractTask                //任务列表
+	ClearTaskList                                map[string]*ClearTask                  //清理任务列表
+	saveLimit                                    = 100                                  //抽取日志批量保存
+	PageSize                                     = 5000                                 //查询分页
+	Fields                                       = `{"jyfb_data":1,"title":1,"summary":1,"detail":1,"contenthtml":1,"site":1,"spidercode":1,"toptype":1,"subtype":1,"bidstatus":1,"area":1,"city":1,"comeintime":1,"publishtime":1,"sensitive":1,"projectinfo":1,"jsondata":1,"href":1,"infoformat":1,"attach_text":1,"dataging":1,"review_experts":1,"purchasing":1}`
 	//Fields        = `{"title":1,"summary":1,"detail":1,"contenthtml":1,"site":1,"spidercode":1,"toptype":1,"subtype":1,"bidstatus":1,"area":1,"city":1,"comeintime":1,"publishtime":1,"sensitive":1,"projectinfo":1,"jsondata":1,"href":1,"infoformat":1,"attach_text":1,"dataging":1,"new_attach_text":1,"createtime":1,"currency":1,"id":1,"company_email":1,"buyerclass":1,"tagname":1,"company_phone":1,"appid":1,"industry":1,"projectscope":1,"item":1,"s_subscopeclass":1,"matchkey":1,"jybxhref":1,"legal_person":1,"matchtype":1,"review_experts":1,"purchasing":1}`
-	Fields2 = `{"budget":1,"bidamount":1,"title":1,"projectname":1,"winner":1}`
+	Fields2    = `{"budget":1,"bidamount":1,"title":1,"projectname":1,"winner":1}`
 	spidercode = map[string]bool{
 		"gd_zhsggzyjyzx_jsgc_fjczbgg":     true,
 		"js_szgyyqggzyjyzx_jsgc_zjfbgs":   true,
@@ -67,7 +67,6 @@ var (
 
 //var packageUnUsedReg = regexp.MustCompile("1[0-9].投标报价\n1[0-9].1")
 
-
 //启动测试抽取-、、、、结果追踪
 func StartExtractTestTask(taskId, startId, num, resultcoll, trackcoll string) bool {
 	defer qu.Catch()
@@ -152,7 +151,7 @@ func RunExtractTestTask(ext *ExtractTask, startId, num string) bool {
 			if ext.IsFileField && (v["projectinfo"] != nil || v["attach_text"] != nil) {
 				v["isextFile"] = true
 				j, jf, isSite = ext.PreInfo(v)
-			} else {//无附件
+			} else { //无附件
 				j, _, isSite = ext.PreInfo(v)
 			}
 			go ext.ExtractProcess(j, jf, isSite) //抽取-打分-保存
@@ -329,11 +328,6 @@ func (e *ExtractTask) PreInfo(doc map[string]interface{}) (j, jf *ju.Job, isSite
 		file2text(&doc) //附件文本堆一起(后期可以考虑,分开处理),方法里修改了doc["detailfile"]结果
 	}
 
-
-
-
-
-
 	//正文小于200个字,有附件把附件内容加到正文
 	//tmpDeatil := detail
 	//tmpdocument, err := goquery.NewDocumentFromReader(strings.NewReader(tmpDeatil))
@@ -356,10 +350,10 @@ func (e *ExtractTask) PreInfo(doc map[string]interface{}) (j, jf *ju.Job, isSite
 	if qu.ObjToString(doc["type"]) == "bid" {
 		toptype = "结果"
 	}
-	if toptype == "" || toptype=="采购意向" {
+	if toptype == "" || toptype == "采购意向" {
 		toptype = "all"
 	}
-	if subtype == "" || subtype=="采购意向" {
+	if subtype == "" || subtype == "采购意向" {
 		subtype = "all"
 	}
 	if subtype == "其他" {
@@ -405,7 +399,7 @@ func (e *ExtractTask) PreInfo(doc map[string]interface{}) (j, jf *ju.Job, isSite
 		RuleBlock:     e.RuleBlock,
 		Dataging:      qu.IntAll(doc["dataging"]),
 		IsClearnMoney: isClearnMoneystr,
-		IsUnRulesTab :	false,
+		IsUnRulesTab:  false,
 	}
 	if isextFile {
 		jf = &ju.Job{
@@ -426,7 +420,7 @@ func (e *ExtractTask) PreInfo(doc map[string]interface{}) (j, jf *ju.Job, isSite
 			IsFile:         isextFile,
 			Dataging:       qu.IntAll(doc["dataging"]),
 			IsClearnMoney:  isClearnMoneystr,
-			IsUnRulesTab :	false,
+			IsUnRulesTab:   false,
 		}
 	}
 	codeSite := j.SpiderCode
@@ -517,21 +511,21 @@ func file2text(doc *map[string]interface{}) {
 }
 
 //判断-附件分包是否有效
-func isUsedPackageJF(jf_package map[string]map[string]interface{})bool {
-	if jf_package == nil ||  len(jf_package) == 0 {
+func isUsedPackageJF(jf_package map[string]map[string]interface{}) bool {
+	if jf_package == nil || len(jf_package) == 0 {
 		return false
 	}
-	for _,pack := range jf_package {
+	for _, pack := range jf_package {
 		budget := qu.Float64All(pack["budget"])
 		bidamount := qu.Float64All(pack["bidamount"])
 		//winner := qu.Float64All(pack["winner"])
 		//text := qu.ObjToString(pack["text"])
 		//13.投标报价\n13.1本次报价
 		//14.投标报价\n14.1投标报价
-		if budget >0.0  && budget <= 1.0 {
+		if budget > 0.0 && budget <= 1.0 {
 			return false
 		}
-		if bidamount >0.0  && bidamount <= 1.0 {
+		if bidamount > 0.0 && bidamount <= 1.0 {
 			return false
 		}
 	}
@@ -541,7 +535,7 @@ func isUsedPackageJF(jf_package map[string]map[string]interface{})bool {
 //抽取-正文
 func (e *ExtractTask) ExtractProcess(j, jf *ju.Job, isSite bool) {
 	e.ExtractDetail(j, isSite, j.SpiderCode) //正文抽取属性
-	if jf != nil && jf.IsFile { //附件jf → j  合并
+	if jf != nil && jf.IsFile {              //附件jf → j  合并
 		e.ExtractDetail(jf, isSite, j.SpiderCode)
 		for tmpk, xs := range jf.Result {
 			if len(j.Result[tmpk]) == 0 {
@@ -552,32 +546,40 @@ func (e *ExtractTask) ExtractProcess(j, jf *ju.Job, isSite bool) {
 						}
 					}
 				} else {
+					if tmpk == "winner" && j.Category == "招标" && j.CategorySecond != "单一" {
+						//log.Debug("不采用~招标类附件中标信息")
+						continue
+					}
 					j.Result[tmpk] = append(j.Result[tmpk], jf.Result[tmpk]...)
 				}
-			}else {
-				if tmpk=="winner" {
-					//均没有有效值~采用附件的
+			} else {
+				if tmpk == "winner" { //均没有有效值~采用附件的
 					isUsed := false
-					for _,v := range j.Result[tmpk] {
-						if v.Value!="" {
+					for _, v := range j.Result[tmpk] {
+						if v.Value != "" {
 							isUsed = true
 							break
 						}
 					}
 					if !isUsed {
+						if j.Category == "招标" && j.CategorySecond != "单一" {
+							//log.Debug("不采用~招标类附件中标信息~")
+							continue
+						}
 						j.Result[tmpk] = append(j.Result[tmpk], jf.Result[tmpk]...)
 					}
 				}
-				//if tmpk=="buyer" { //附件数据-没有正文靠谱
-				//	j.Result[tmpk] = append(j.Result[tmpk], jf.Result[tmpk]...)
-				//}
 			}
 		}
 		if len(j.Winnerorder) == 0 && jf.Winnerorder != nil && len(jf.Winnerorder) > 0 {
-			j.Winnerorder = append(j.Winnerorder, jf.Winnerorder...)
+			if j.Category == "招标" && j.CategorySecond != "单一" {
+				//log.Debug("不采用~招标类附件中标信息~~")
+			} else {
+				j.Winnerorder = append(j.Winnerorder, jf.Winnerorder...)
+			}
 		}
-		if len(j.PackageInfo) == 0 &&  isUsedPackageJF(jf.PackageInfo) {
-			j.PackageInfo =  jf.PackageInfo
+		if len(j.PackageInfo) == 0 && isUsedPackageJF(jf.PackageInfo) {
+			j.PackageInfo = jf.PackageInfo
 		}
 	}
 	if isSite {
@@ -684,7 +686,7 @@ func (e *ExtractTask) ExtractDetail(j *ju.Job, isSite bool, codeSite string) {
 					continue
 				}
 
-				if vc.Field =="signendtime" {
+				if vc.Field == "addressing" {
 					//log.Debug("调试抽取字段")
 				}
 				////抽取-前置规则
@@ -785,9 +787,9 @@ func (e *ExtractTask) ExtractDetail(j *ju.Job, isSite bool, codeSite string) {
 					text := qu.ObjToString(v.Value)
 					before = text
 					//指定清理--新增-函数清理-其他清理
-					if key=="winner"||key=="agency"||key=="buyer" {
-						text = strings.ReplaceAll(text,"【","")
-						text = strings.ReplaceAll(text,"】","")
+					if key == "winner" || key == "agency" || key == "buyer" {
+						text = strings.ReplaceAll(text, "【", "")
+						text = strings.ReplaceAll(text, "】", "")
 					}
 					v.Value = clear.OtherClean(key, text)
 					BeforeAddClearFnLog("clear.OtherClean", "特殊符号清理clear.OtherClean", j.SourceMid, before, v.MatchType, v, e)
@@ -1117,7 +1119,7 @@ func ExtRuleCoreByPkgReg(j *ju.Job, in *RegLuaInfo, e *ExtractTask) {
 	//块抽取
 	if in.Field != "" {
 		//临时调试分包抽取字段-
-		if in.Field=="bidamount" {
+		if in.Field == "bidamount" {
 			//log.Debug("分包-调试字段...")
 		}
 		for k, vbpkg := range j.BlockPackage {
@@ -1233,7 +1235,7 @@ func ExtRuleCoreByPkgReg(j *ju.Job, in *RegLuaInfo, e *ExtractTask) {
 									j.BlockPackage[k].IsTrueAgencyfee = true
 								}
 								break
-							}else if in.Field == "bidamount" && vbpkg.Bidamount <= 0 {
+							} else if in.Field == "bidamount" && vbpkg.Bidamount <= 0 {
 								lock.Lock()
 								cfn := e.ClearFn[in.Field]
 								lock.Unlock()
@@ -1656,10 +1658,10 @@ func ExtRegBack(j *ju.Job, in *RegLuaInfo, t *TaskInfo, vc *RuleCore) {
 					}
 					text := qu.ObjToString(v.Value)
 					if v.Field == "bidamount" || v.Field == "budget" {
-						if (strings.Contains(qu.ObjToString(v.SourceValue), "费率")||
+						if (strings.Contains(qu.ObjToString(v.SourceValue), "费率") ||
 							strings.Contains(qu.ObjToString(v.SourceValue), "税率") ||
-							strings.Contains(qu.ObjToString(v.SourceValue), "(%)") ) &&
-							!strings.Contains(qu.ObjToString(v.SourceValue), "工程设计费"){
+							strings.Contains(qu.ObjToString(v.SourceValue), "(%)")) &&
+							!strings.Contains(qu.ObjToString(v.SourceValue), "工程设计费") {
 							j.Result[in.Field][k].IsTrue = false
 							continue
 						}
@@ -1753,7 +1755,7 @@ func ExtRuleKV(j *ju.Job, in *RegLuaInfo, t *TaskInfo) {
 				if v.Type != "table" && !strings.Contains(v.Type, "colon") && !strings.Contains(v.Type, "space") {
 					continue
 				}
-				if v.Field=="docendtime" {
+				if v.Field == "docendtime" {
 					//log.Debug("调试字段...")
 				}
 				text := qu.ObjToString(v.Value)
@@ -1903,74 +1905,74 @@ type FieldValue struct {
 
 var clearWinnerReg = regexp.MustCompile("名称|施工|拟定供应商名称|:|:")
 var unPackageWinnerReg = regexp.MustCompile("(重新招标)")
+
 //包含字母的实体单位
 var letter_entity = regexp.MustCompile("^[\u4E00-\u9FA5]{1,10}[A-Za-z]{1,5}[\u4E00-\u9FA5]{1,10}(公司|集团|单位|机构|企业|厂|场|院|所|店|中心|市|局|站|城|处|行|部|队|联合[会|体])$")
 
-
 //特殊金额-处理判断-倍率关系
-func calculateAbnormalMoney(val []*ju.ExtField) (bool,int) {
+func calculateAbnormalMoney(val []*ju.ExtField) (bool, int) {
 	//金额结果只有两种 - 倍率关系10000 - 过10E
 	moneyIndex := []int{}
 	moneyArr := []float64{}
 	difValue := map[string]interface{}{}
 	for k, v := range val { //取第一个非负数,项目名称除外
-		if  v.IsTrue && v.Score > -1 {
-			moneyArr = append(moneyArr,qu.Float64All(v.Value))
-			moneyIndex = append(moneyIndex,k)
+		if v.IsTrue && v.Score > -1 {
+			moneyArr = append(moneyArr, qu.Float64All(v.Value))
+			moneyIndex = append(moneyIndex, k)
 			key := ""
-			if m,ok := v.Value.(float64);ok {
-				key = fmt.Sprintf("%f",m)
-			}else {
+			if m, ok := v.Value.(float64); ok {
+				key = fmt.Sprintf("%f", m)
+			} else {
 				key = qu.ObjToString(v.Value)
 			}
-			if difValue[key]==nil {
+			if difValue[key] == nil {
 				difValue[key] = 1
 			}
-			if len(difValue)>2 {
-				return false,0
+			if len(difValue) > 2 {
+				return false, 0
 			}
 		}
 	}
 	//计算金额数组
-	if len(difValue)==2 {
-		money_1,money_2 := float64(0),float64(0)
-		for k,v := range moneyArr{
-			if k==0 {
-				money_1=v
-			}else {
-				if v!=money_1 {
-					money_2=v
+	if len(difValue) == 2 {
+		money_1, money_2 := float64(0), float64(0)
+		for k, v := range moneyArr {
+			if k == 0 {
+				money_1 = v
+			} else {
+				if v != money_1 {
+					money_2 = v
 					break
 				}
 			}
 		}
-		isRatio,new_money:= false,float64(0)  //判断金额是否为倍率关系
-		if money_1!=float64(0)&&money_2!=float64(0) {
-			if money_1 == money_2*float64(10000) && money_1>=1000000000{
+		isRatio, new_money := false, float64(0) //判断金额是否为倍率关系
+		if money_1 != float64(0) && money_2 != float64(0) {
+			if money_1 == money_2*float64(10000) && money_1 >= 100000000 {
 				isRatio = true
 				new_money = money_2
 			}
-			if money_2 == money_1*float64(10000) && money_2>=1000000000{
+			if money_2 == money_1*float64(10000) && money_2 >= 100000000 {
 				isRatio = true
 				new_money = money_1
 			}
 
 			if isRatio { //采用新值
-				for k,v := range moneyArr{
-					if v==new_money {
-						return true,moneyIndex[k]
+				for k, v := range moneyArr {
+					if v == new_money {
+						return true, moneyIndex[k]
 					}
 				}
 			}
 		}
 	}
-	return false,0
+	return false, 0
 }
 
-
 //分析抽取结果并保存
 func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 	qu.Try(func() {
+		//(j.Category == "招标" || j.Category == "预告")
 		if (j.Category == "招标" || j.Category == "预告") && (len(j.BlockPackage) > 0 || len(j.PackageInfo) > 0 || len(j.Result) > 0) {
 			if j.CategorySecond != "单一" {
 				delete(j.Result, "winner")
@@ -2018,7 +2020,7 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 		}
 
 		//字段-抽取来源
-		fieldSource := make(map[string]interface{},0)
+		fieldSource := make(map[string]interface{}, 0)
 		//字段-抽取来源
 		for k, val := range result {
 			if k == "qualifies" {
@@ -2053,14 +2055,14 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 			}
 
 			//预算-中标金额字段-特殊情况特殊处理
-			if k=="bidamount" || k=="budget" {
-				b,index :=calculateAbnormalMoney(val)
+			if k == "bidamount" || k == "budget" {
+				b, index := calculateAbnormalMoney(val)
 				if b {
 					new_v := val[index]
 					tmp[new_v.Field] = new_v.Value
 					fieldSource[new_v.Field] = map[string]interface{}{
-						"ext_type":new_v.Type,
-						"ext_from":new_v.ExtFrom,
+						"ext_type": new_v.Type,
+						"ext_from": new_v.ExtFrom,
 					}
 					tmp["is_dif_ratioMoney"] = true
 					continue
@@ -2071,24 +2073,24 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 				if (v.Field == "bidamount" || v.Field == "budget") && v.IsTrue && v.Score > -1 {
 					tmp[v.Field] = v.Value
 					fieldSource[v.Field] = map[string]interface{}{
-						"ext_type":v.Type,
-						"ext_from":v.ExtFrom,
+						"ext_type": v.Type,
+						"ext_from": v.ExtFrom,
 					}
 					break
 				}
 				if v.Score > -1 && (v.Field != "bidamount" && v.Field != "budget") && len(strings.TrimSpace(fmt.Sprint(v.Value))) > 0 {
 					tmp[v.Field] = v.Value
 					fieldSource[v.Field] = map[string]interface{}{
-						"ext_type":v.Type,
-						"ext_from":v.ExtFrom,
+						"ext_type": v.Type,
+						"ext_from": v.ExtFrom,
 					}
 					//中标单位~含字母判断~对比企业库
-					if (v.Field =="winner"||v.Field=="buyer") && letter_entity.MatchString(qu.ObjToString(v.SourceValue)){
+					if (v.Field == "winner" || v.Field == "buyer") && letter_entity.MatchString(qu.ObjToString(v.SourceValue)) {
 						qyxy_data := make([]map[string]interface{}, 0)
 						ju.QyxySess.Find(map[string]interface{}{
 							"company_name": qu.ObjToString(v.SourceValue),
 						}).All(&qyxy_data)
-						if qyxy_data!=nil && len(qyxy_data)>0 {
+						if qyxy_data != nil && len(qyxy_data) > 0 {
 							tmp[v.Field] = v.SourceValue
 						}
 					}
@@ -2108,7 +2110,7 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 		if len(j.PackageInfo) > 0 { //分包信息
 			tmp["package"] = j.PackageInfo
 			//包预算,中标金额合并大于抽取就覆盖
-			tmpBidamount, tmpBudget,tmpAgencyfee:=qu.Float64All(0),qu.Float64All(0),qu.Float64All(0)
+			tmpBidamount, tmpBudget, tmpAgencyfee := qu.Float64All(0), qu.Float64All(0), qu.Float64All(0)
 			//s_winner逗号分隔拼接,分包中标人
 			var tmpstr, savewinner []string
 			//按包排序
@@ -2122,35 +2124,35 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 				//包数大于1累加
 				for _, v := range j.PackageInfo {
 					if v["budget"] != nil {
-						tmpBudget = precisionAddFloat(tmpBudget,qu.Float64All(v["budget"]))
+						tmpBudget = precisionAddFloat(tmpBudget, qu.Float64All(v["budget"]))
 					}
 					if v["bidamount"] != nil {
-						tmpBidamount = precisionAddFloat(tmpBidamount,qu.Float64All(v["bidamount"]))
+						tmpBidamount = precisionAddFloat(tmpBidamount, qu.Float64All(v["bidamount"]))
 					}
 					if v["agencyfee"] != nil {
-						tmpAgencyfee = precisionAddFloat(tmpAgencyfee,qu.Float64All(v["agencyfee"]))
+						tmpAgencyfee = precisionAddFloat(tmpAgencyfee, qu.Float64All(v["agencyfee"]))
 					}
 				}
 				if qu.Float64All(tmp["budget"]) < tmpBudget {
 					fieldSource["budget"] = map[string]interface{}{
-						"ext_type":"",
-						"ext_from":"package",
+						"ext_type": "",
+						"ext_from": "package",
 					}
 					tmp["budget"] = tmpBudget
 				}
 
 				if qu.Float64All(tmp["agencyfee"]) < tmpAgencyfee {
 					fieldSource["agencyfee"] = map[string]interface{}{
-						"ext_type":"",
-						"ext_from":"package",
+						"ext_type": "",
+						"ext_from": "package",
 					}
 					tmp["agencyfee"] = tmpAgencyfee
 				}
 
 				if qu.Float64All(tmp["bidamount"]) > 0 && qu.Float64All(tmp["budget"]) > 0 && (qu.Float64All(tmp["bidamount"])/10 > qu.Float64All(tmp["budget"])) {
 					fieldSource["bidamount"] = map[string]interface{}{
-						"ext_type":"",
-						"ext_from":"package",
+						"ext_type": "",
+						"ext_from": "package",
 					}
 					tmp["bidamount"] = tmpBidamount
 				} else if qu.Float64All(tmp["bidamount"]) < tmpBidamount {
@@ -2166,8 +2168,8 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 					for _, v := range j.PackageInfo {
 						if v["budget"] != nil {
 							fieldSource["budget"] = map[string]interface{}{
-								"ext_type":"",
-								"ext_from":"package",
+								"ext_type": "",
+								"ext_from": "package",
 							}
 							tmp["budget"] = v["budget"]
 						}
@@ -2178,8 +2180,8 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 					for _, v := range j.PackageInfo {
 						if v["agencyfee"] != nil {
 							fieldSource["agencyfee"] = map[string]interface{}{
-								"ext_type":"",
-								"ext_from":"package",
+								"ext_type": "",
+								"ext_from": "package",
 							}
 							tmp["agencyfee"] = v["agencyfee"]
 						}
@@ -2190,8 +2192,8 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 					for _, v := range j.PackageInfo {
 						if v["bidamount"] != nil {
 							fieldSource["bidamount"] = map[string]interface{}{
-								"ext_type":"",
-								"ext_from":"package",
+								"ext_type": "",
+								"ext_from": "package",
 							}
 							tmp["bidamount"] = v["bidamount"]
 						}
@@ -2207,7 +2209,7 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 					continue
 				}
 				//名称黑名单
-				if unPackageWinnerReg.MatchString(new_winner)  {
+				if unPackageWinnerReg.MatchString(new_winner) {
 					continue
 				}
 				savewinner = append(savewinner, new_winner)
@@ -2216,15 +2218,15 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 				tmp["s_winner"] = tmp["winner"]
 				fieldSource["s_winner"] = fieldSource["winner"]
 			} else if savewinner != nil {
-				if len(savewinner)==1 && tmp["winner"] != nil {
+				if len(savewinner) == 1 && tmp["winner"] != nil {
 					tmp["s_winner"] = tmp["winner"]
 					fieldSource["s_winner"] = fieldSource["winner"]
-				}else {
+				} else {
 					savewinner = RemoveReplicaSliceString(savewinner)
 					tmp["s_winner"] = strings.Join(savewinner, ",")
 					fieldSource["s_winner"] = map[string]interface{}{
-						"ext_type":"",
-						"ext_from":"package",
+						"ext_type": "",
+						"ext_from": "package",
 					}
 				}
 			}
@@ -2260,24 +2262,27 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 							if (v.Field == "bidamount" || v.Field == "budget") && v.IsTrue && v.Value.(float64) > 100 && v.Value.(float64) < 50000000000 {
 								tmp[v.Field] = v.Value
 								fieldSource[v.Field] = map[string]interface{}{
-									"ext_type":v.Type,
-									"ext_from":"ff",
+									"ext_type": v.Type,
+									"ext_from": "ff",
 								}
 								break
 							}
 							if v.Score > -1 && (v.Field != "bidamount" && v.Field != "budget") && len(strings.TrimSpace(fmt.Sprint(v.Value))) > 0 {
+								if v.Field == "winner" && j.Category == "招标" && j.CategorySecond != "单一" {
+									break //此方法逻辑上已经不会达到这里 winner
+								}
 								tmp[v.Field] = v.Value
 								fieldSource[v.Field] = map[string]interface{}{
-									"ext_type":v.Type,
-									"ext_from":"ff",
+									"ext_type": v.Type,
+									"ext_from": "ff",
 								}
 								//中标单位~含字母判断~对比企业库
-								if (v.Field =="winner" || v.Field=="buyer") && letter_entity.MatchString(qu.ObjToString(v.SourceValue)){
+								if (v.Field == "winner" || v.Field == "buyer") && letter_entity.MatchString(qu.ObjToString(v.SourceValue)) {
 									qyxy_data := make([]map[string]interface{}, 0)
 									ju.QyxySess.Find(map[string]interface{}{
 										"company_name": qu.ObjToString(v.SourceValue),
 									}).All(&qyxy_data)
-									if qyxy_data!=nil && len(qyxy_data)>0 {
+									if qyxy_data != nil && len(qyxy_data) > 0 {
 										tmp[v.Field] = v.SourceValue
 									}
 								}
@@ -2301,7 +2306,7 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 		tmp["field_source"] = fieldSource
 		//是否为不规则表格字段
 		if j.IsUnRulesTab {
-			tmp["is_UnRules_Tab"]= j.IsUnRulesTab
+			tmp["is_UnRules_Tab"] = j.IsUnRulesTab
 		}
 		for k, v := range *doc {
 			if utf8.RuneCountInString(qu.ObjToString(v)) > 100000 {
@@ -2415,9 +2420,9 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 				delete(tmp,k)
 			}
 		}*/
-		//检查字段
-		tmp = checkFields(tmp,*j.Data)
 
+		//检查字段
+		tmp = checkFields(tmp, *j.Data)
 
 		if tmp["projectname"] == nil || tmp["projectname"] == "" {
 			tmp["projectname"] = j.Title
@@ -2491,36 +2496,47 @@ func AnalysisSaveResult(j, jf *ju.Job, e *ExtractTask) {
 }
 
 //检查字段-
-func checkFields(tmp map[string]interface{},j_data map[string]interface{}) map[string]interface{} {
+func checkFields(tmp map[string]interface{}, j_data map[string]interface{}) map[string]interface{} {
 	delete(tmp, "contenthtml")
 	delete(tmp, "detail")
-	tmp["repeat"] = 0
 
+	//对于招标类信息~若winner没有值~过滤掉中标相关信息
+	if qu.ObjToString(tmp["toptype"]) == "招标" &&
+		qu.ObjToString(tmp["subtype"]) != "单一" {
+		delete(tmp, "winner")
+		delete(tmp, "s_winner")
+		delete(tmp, "bidamount")
+		delete(tmp, "winnerorder")
+		//if qu.ObjToString(tmp["winner"])=="" || qu.ObjToString(tmp["winner"])=="有限公司"{
+		//	delete(tmp,"winner")
+		//	delete(tmp,"s_winner")
+		//	delete(tmp,"bidamount")
+		//	delete(tmp,"winnerorder")
+		//}
+	}
+
+	tmp["repeat"] = 0
 	//指定爬虫-金额处理-预算-中标金额异常
-	if qu.ObjToString(tmp["spidercode"])=="xz_xzzzqjzscjgycxxxpt_zbtzs" {
-		if budget, ok := tmp["budget"].(float64); ok && budget>0 && budget < 1000000{
-			tmp["budget"] = budget*10000.0
+	if qu.ObjToString(tmp["spidercode"]) == "xz_xzzzqjzscjgycxxxpt_zbtzs" {
+		if budget, ok := tmp["budget"].(float64); ok && budget > 0 && budget < 1000000 {
+			tmp["budget"] = budget * 10000.0
 		}
-		if bidamount, ok := tmp["bidamount"].(float64); ok && bidamount>0 && bidamount > 1000000000{
-			tmp["bidamount"] = bidamount/10000.0
+		if bidamount, ok := tmp["bidamount"].(float64); ok && bidamount > 0 && bidamount > 1000000000 {
+			tmp["bidamount"] = bidamount / 10000.0
 		}
 	}
-	if qu.ObjToString(tmp["spidercode"])=="js_jsszbtbw_zbhxrgs" {
-		if bidamount, ok := tmp["bidamount"].(float64); ok && bidamount>0 && bidamount > 1000000000{
-			tmp["bidamount"] = bidamount/10000.0
+	if qu.ObjToString(tmp["spidercode"]) == "js_jsszbtbw_zbhxrgs" {
+		if bidamount, ok := tmp["bidamount"].(float64); ok && bidamount > 0 && bidamount > 1000000000 {
+			tmp["bidamount"] = bidamount / 10000.0
 		}
 	}
 
-
-
-
-
 	//金额比例异常-
 	if _, ok := tmp["bidamount"].(string); ok {
 		delete(tmp, "bidamount")
 	} else if fb, ok := tmp["bidamount"].(float64); ok && fb > 0 && qu.Float64All(tmp["budget"]) > 0 && (fb/10 > qu.Float64All(tmp["budget"]) || qu.Float64All(tmp["budget"])/1000 > fb) {
-		if fb>1000.0 &&fb<100000000.0{
-		}else {
+		if fb > 1000.0 && fb < 100000000.0 {
+		} else {
 			delete(tmp, "bidamount")
 		}
 	}
@@ -2557,7 +2573,7 @@ func checkFields(tmp map[string]interface{},j_data map[string]interface{}) map[s
 
 	//项目周期-有效值
 	projectperiod := qu.ObjToString(tmp["projectperiod"])
-	if projectperiod !="" {
+	if projectperiod != "" {
 		//项目周期包含日期,数字及日期单位可保留,其余可清洗
 		isNeedValueReg := regexp.MustCompile(`([0-9俩两一二三四五六七八九年月日天周]|合同)`)
 		if !isNeedValueReg.MatchString(projectperiod) {
@@ -2568,11 +2584,11 @@ func checkFields(tmp map[string]interface{},j_data map[string]interface{}) map[s
 	//工期单位是否有效-清理
 	if project_timeunit, ok := tmp["project_timeunit"].(string); ok {
 		dateReg := regexp.MustCompile(`[年|月|日|天|周]`)
-		if !dateReg.MatchString(project_timeunit) || utf8.RuneCountInString(project_timeunit)>4 {
+		if !dateReg.MatchString(project_timeunit) || utf8.RuneCountInString(project_timeunit) > 4 {
 			delete(tmp, "project_timeunit")
 		}
 		//年-0 >5 删除
-		if project_timeunit == "年" && (qu.Int64All(tmp["project_duration"])==0 || qu.Int64All(tmp["project_duration"])>5 ){
+		if project_timeunit == "年" && (qu.Int64All(tmp["project_duration"]) == 0 || qu.Int64All(tmp["project_duration"]) > 5) {
 			delete(tmp, "project_timeunit")
 		}
 	}
@@ -2594,7 +2610,7 @@ func checkFields(tmp map[string]interface{},j_data map[string]interface{}) map[s
 	if bg, ok := tmp["bidamount"].(float64); ok && bg >= 50000000000 {
 		code := qu.ObjToString(tmp["spidercode"])
 		if bg >= 50000000000 && code != "xz_xzzzqjzscjgycxxxpt_zbtzs" &&
-			code != "js_jsszbtbw_zbhxrgs"{
+			code != "js_jsszbtbw_zbhxrgs" {
 			tmp["bidamount_max_err"] = bg
 			delete(tmp, "bidamount")
 		}
@@ -2603,21 +2619,22 @@ func checkFields(tmp map[string]interface{},j_data map[string]interface{}) map[s
 	bidway := qu.IntAll(tmp["bidway"])
 	if bidway == 1 {
 		tmp["bidway"] = "纸质投标"
-	}else if bidway == 2 {
+	} else if bidway == 2 {
 		tmp["bidway"] = "电子投标"
-	}else {
+	} else {
 		delete(tmp, "bidway")
 	}
 
 	//折扣系数
 	discount := dealWithDiscountBid(tmp)
-	if discount >0.0 {
+	if discount > 0.0 {
 		tmp["biddiscount"] = discount
-	}else {
+	} else {
 		delete(tmp, "biddiscount")
 	}
 	delete(tmp, "biddiscount_up")
 	delete(tmp, "biddiscount_down")
+	delete(tmp, "addressing")
 
 	//临时
 	//bidstarttime := qu.Int64All(tmp["bidstarttime"])
@@ -2633,16 +2650,15 @@ func checkFields(tmp map[string]interface{},j_data map[string]interface{}) map[s
 	//	tmp["docendtime"] = time_2
 	//}
 
-	jyhref:= fmt.Sprintf(JYUrl, qu.CommonEncodeArticle("content", qu.BsonIdToSId(tmp["_id"])))
+	jyhref := fmt.Sprintf(JYUrl, qu.CommonEncodeArticle("content", qu.BsonIdToSId(tmp["_id"])))
 	tmp["jytest_href"] = jyhref
 
-
 	//检查剑鱼发布-爬虫
 	jyfb_data := *qu.ObjToMap(j_data["jyfb_data"])
-	if jyfb_data!=nil {
-		for k,v := range jyfb_data{
-			if k=="area" {
-				delete(tmp,"district")
+	if jyfb_data != nil {
+		for k, v := range jyfb_data {
+			if k == "area" {
+				delete(tmp, "district")
 			}
 			tmp[k] = v
 		}
@@ -2657,59 +2673,53 @@ func dealWithDiscountBid(tmp map[string]interface{}) float64 {
 	biddiscount_down := qu.Float64All(tmp["biddiscount_down"])
 
 	baseCount := float64(1)
-	if biddiscount_down >0.0 {
-		num1:=decimal.NewFromFloat(baseCount)
-		num2:=decimal.NewFromFloat(biddiscount_down)
+	if biddiscount_down > 0.0 {
+		num1 := decimal.NewFromFloat(baseCount)
+		num2 := decimal.NewFromFloat(biddiscount_down)
 		decimalValue := num1.Sub(num2)
-		res,_ := decimalValue.Float64()
-		//log.Debug("下浮后折扣系数:",res)
+		res, _ := decimalValue.Float64()
 		return res
 	}
-	if biddiscount_up >0.0 {
-		num1:=decimal.NewFromFloat(baseCount)
-		num2:=decimal.NewFromFloat(biddiscount_up)
+	if biddiscount_up > 0.0 {
+		num1 := decimal.NewFromFloat(baseCount)
+		num2 := decimal.NewFromFloat(biddiscount_up)
 		decimalValue := num1.Add(num2)
-		res,_ := decimalValue.Float64()
+		res, _ := decimalValue.Float64()
 		//log.Debug("上浮后折扣系数:",res)
 		return res
 	}
-	if biddiscount>0.0 {
-		if biddiscount > 1.0 && biddiscount<=10.0  {
-			num1:=decimal.NewFromFloat(10.0)
-			num2:=decimal.NewFromFloat(biddiscount)
+	if biddiscount > 0.0 {
+		if biddiscount > 1.0 && biddiscount <= 10.0 {
+			num1 := decimal.NewFromFloat(10.0)
+			num2 := decimal.NewFromFloat(biddiscount)
 			decimalValue := num2.Div(num1)
-			res,_ := decimalValue.Float64()
-			//log.Debug("标准-①折扣系数:",res)
+			res, _ := decimalValue.Float64()
 			return res
-		}else if biddiscount>10.0 {
-			num1:=decimal.NewFromFloat(100.0)
-			num2:=decimal.NewFromFloat(biddiscount)
+		} else if biddiscount > 10.0 {
+			num1 := decimal.NewFromFloat(100.0)
+			num2 := decimal.NewFromFloat(biddiscount)
 			decimalValue := num2.Div(num1)
-			res,_ := decimalValue.Float64()
+			res, _ := decimalValue.Float64()
 			//log.Debug("标准-⑩折扣系数:",res)
 			return res
-		}else {
+		} else {
 			//log.Debug("标准折扣系数:",biddiscount)
 			return biddiscount
 		}
 	}
 
-
 	return 0.0
 }
+
 //精度丢失-相加
-func precisionAddFloat(tmp1,tmp2 float64)float64{
-	num1:=decimal.NewFromFloat(tmp1)
-	num2:=decimal.NewFromFloat(tmp2)
+func precisionAddFloat(tmp1, tmp2 float64) float64 {
+	num1 := decimal.NewFromFloat(tmp1)
+	num2 := decimal.NewFromFloat(tmp2)
 	decimalValue := num2.Add(num1)
-	res,_ := decimalValue.Float64()
+	res, _ := decimalValue.Float64()
 	return res
 }
 
-
-
-
-
 //保存其他
 //kv、表格、块上的标签凡是新的标签都入库
 //val  type   times   firstid  createtime 判定field
@@ -3014,29 +3024,29 @@ func (e *ExtractTask) StartMatch(field, text string) *pretreated.SortMap {
 
 //筛选重复候选人-相关
 func filterRepeatWinArr(j *ju.Job) {
-	if j.SpiderCode=="sh_shszfhcxjsglwyh_jsgc_zhbhxrgs" {
-		sort_WinOrder_Arr := make([][]map[string]interface{},0)
-		sort_arr := make([]map[string]interface{},0)
-		for _,v := range j.Winnerorder{
+	if j.SpiderCode == "sh_shszfhcxjsglwyh_jsgc_zhbhxrgs" {
+		sort_WinOrder_Arr := make([][]map[string]interface{}, 0)
+		sort_arr := make([]map[string]interface{}, 0)
+		for _, v := range j.Winnerorder {
 			sort := qu.IntAll(v["sort"])
-			if sort==1 { //为一组
-				if len(sort_arr)>0 {
-					sort_WinOrder_Arr = append(sort_WinOrder_Arr,sort_arr)
+			if sort == 1 { //为一组
+				if len(sort_arr) > 0 {
+					sort_WinOrder_Arr = append(sort_WinOrder_Arr, sort_arr)
 				}
-				sort_arr = make([]map[string]interface{},0)
+				sort_arr = make([]map[string]interface{}, 0)
 			}
-			sort_arr = append(sort_arr,v)
+			sort_arr = append(sort_arr, v)
 		}
 
-		if len(sort_arr)>0 {
-			sort_WinOrder_Arr = append(sort_WinOrder_Arr,sort_arr)
+		if len(sort_arr) > 0 {
+			sort_WinOrder_Arr = append(sort_WinOrder_Arr, sort_arr)
 		}
-		if len(sort_WinOrder_Arr)>0 { //有重复排序组-开始筛选清理
-			isIndex :=0
-			for index,winArr := range sort_WinOrder_Arr {
-				if len(winArr)>0 {
-					if qu.ObjToString(winArr[0]["price"])!=""&&
-						qu.ObjToString(winArr[0]["entname"])!="" {
+		if len(sort_WinOrder_Arr) > 0 { //有重复排序组-开始筛选清理
+			isIndex := 0
+			for index, winArr := range sort_WinOrder_Arr {
+				if len(winArr) > 0 {
+					if qu.ObjToString(winArr[0]["price"]) != "" &&
+						qu.ObjToString(winArr[0]["entname"]) != "" {
 						isIndex = index
 						break
 					}

+ 16 - 8
src/jy/extract/extractudp.go

@@ -23,9 +23,12 @@ var IsExtStop bool
 //新增机器节点
 func ExtractUdpUpdateMachine() {
 	machine := *qu.ObjToMap(ju.Config["udpmachine"])
-	skey := fmt.Sprintf("%s:%d:%s",machine["addr"],qu.IntAll(machine["port"]),machine["stype"])
+	if len(machine) == 0 || machine == nil {
+		return
+	}
+	skey := fmt.Sprintf("%s:%d:%s", machine["addr"], qu.IntAll(machine["port"]), machine["stype"])
 	machine["skey"] = skey
-	db.Mgo.Update("extract_control_center", map[string]interface{}{"skey":skey},machine,true,false)
+	db.Mgo.Update("extract_control_center", map[string]interface{}{"skey": skey}, machine, true, false)
 }
 
 //udp通知抽取
@@ -61,9 +64,9 @@ func processUdpMsg(act byte, data []byte, ra *net.UDPAddr) {
 						},
 					}, true, false)
 				log.Debug("分布式抽取完成,可以释放esc实例", qu.ObjToString(rep["ip"]))
-			}else if stype == "stop_extract"{
+			} else if stype == "stop_extract" {
 				IsExtStop = true
-			}else if stype == "heart_extract"{
+			} else if stype == "heart_extract" {
 				skey, _ := rep["skey"].(string)
 				Udpclient.WriteUdp([]byte(skey), mu.OP_NOOP, ra)
 			} else {
@@ -80,14 +83,19 @@ func processUdpMsg(act byte, data []byte, ra *net.UDPAddr) {
 					//新版本控制抽取
 					ExtractByUdp(sid, eid, ra)
 					if !IsExtStop {
-						log.Debug("抽取完成udp通知抽取id段-控制台",udpinfo, sid, "~", eid)
+						log.Debug("抽取完成udp通知抽取id段-控制台", udpinfo, sid, "~", eid)
 						Udpclient.WriteUdp([]byte(udpinfo), mu.OP_NOOP, ra)
-					}else {
-						log.Debug("抽取强制中断udp不通知-控制台",udpinfo, sid, "~", eid)
+					} else {
+						log.Debug("抽取强制中断udp不通知-控制台", udpinfo, sid, "~", eid)
 					}
 
 					//适配重采抽取-发送udp-必须替换
 					//go Udpclient.WriteUdp([]byte(udpinfo), mu.OP_NOOP, ra)
+
+					//发布数据~测试流程
+					//key := sid + "-" + eid + "-" + qu.ObjToString(rep["stype"])
+					//go Udpclient.WriteUdp([]byte(key), mu.OP_NOOP, ra)
+					//
 					//log.Debug("udp通知抽取id段", sid, " ", eid)
 					//ExtractByUdp(sid, eid, ra)
 					//for _, m := range nextNodes {
@@ -105,6 +113,7 @@ func processUdpMsg(act byte, data []byte, ra *net.UDPAddr) {
 					//	}
 					//}
 					//log.Debug("udp通知抽取完成,eid=", eid)
+
 				}
 			}
 		}
@@ -253,7 +262,6 @@ func ExtractByUdp(sid, eid string, ra *net.UDPAddr, instanceId ...string) {
 				//	continue
 				//}
 
-
 				var j, jf *ju.Job
 				var isSite bool
 				if ext.IsFileField && (v["projectinfo"] != nil || v["attach_text"] != nil) {

+ 27 - 42
src/jy/extract/newextractcity.go

@@ -16,8 +16,7 @@ var AgencyReg = []*regexp.Regexp{
 }
 
 var xjbtReg *regexp.Regexp = regexp.MustCompile("^(新疆生产建设兵团|新疆兵团)")
-var sensitiveReg  = regexp.MustCompile("(上一[条篇]|下一[条篇])[::].*")
-
+var sensitiveReg = regexp.MustCompile("(上一[条篇]|下一[条篇])[::].*")
 
 //抽取city
 func (e *ExtractTask) NewExtractCity(j *ju.Job, resulttmp *map[string]interface{}, id string) {
@@ -61,30 +60,27 @@ func (e *ExtractTask) NewExtractCity(j *ju.Job, resulttmp *map[string]interface{
 	sm := NewSortMap()
 	//1.jsondata抽取
 	e.NewGetCityByJsonData(j)
-	//qu.Debug("jsondata打分后结果---", j.FullAreaScore, j.FullCityScore, j.FullDistrictScore)
 	//2.site库抽取
 	e.NewGetCityBySite(j)
-	//qu.Debug("site打分后结果---", j.FullAreaScore, j.FullCityScore, j.FullDistrictScore)
 	//3.采购单位库抽取(暂时没有采购单位库)
-	//buyer, _ := resulttmp["buyer"].(string)
+
 	//4.postcode邮编抽取
 	buyerzipcode := qu.ObjToString((*resulttmp)["buyerzipcode"])
 	e.NewGetCityByPostCode(j, buyerzipcode)
-	//qu.Debug("邮编打分后结果---", buyerzipcode, j.FullAreaScore, j.FullCityScore, j.FullDistrictScore)
 	//5.areacode固话区号抽取
 	buyertel := qu.ObjToString((*resulttmp)["buyertel"])
 	e.NewGetCityByAreaCode(j, buyertel)
-	//qu.Debug("固话打分后结果---", j.FullAreaScore, j.FullCityScore, j.FullDistrictScore)
 	//6.buyeraddr,title,projectname抽取
 	buyeraddr := qu.ObjToString((*resulttmp)["buyeraddr"])
 	title := qu.ObjToString((*resulttmp)["title"])
 	projectname := qu.ObjToString((*resulttmp)["projectname"])
 	buyer := qu.ObjToString((*resulttmp)["buyer"])
-	//qu.Debug("buyeraddr--", buyeraddr, "--buyer--", buyer, "--title--", title, "--projectname--", projectname)
+	addressing := qu.ObjToString((*resulttmp)["addressing"])
 	sm.AddKey("buyeraddr", buyeraddr)
 	sm.AddKey("buyer", buyer)
 	sm.AddKey("title", title)
 	sm.AddKey("projectname", projectname)
+	sm.AddKey("addressing", addressing) //新增地址辅助字段
 	if projectaddr, isok := (*resulttmp)["projectaddr"].(string); isok {
 		sm.AddKey("projectaddr", projectaddr)
 	}
@@ -176,8 +172,8 @@ func (e *ExtractTask) NewExtractCity(j *ju.Job, resulttmp *map[string]interface{
 	(*resulttmp)["district"] = districtresult
 
 	//校验-映射新疆兵团
-	if xjbtReg.MatchString(buyer) && cityresult==""  {
-		a,c,d,ok := e.CheckingXjbtCity(buyer)
+	if xjbtReg.MatchString(buyer) && cityresult == "" {
+		a, c, d, ok := e.CheckingXjbtCity(buyer)
 		if ok {
 			(*resulttmp)["area"] = a
 			(*resulttmp)["city"] = c
@@ -186,18 +182,14 @@ func (e *ExtractTask) NewExtractCity(j *ju.Job, resulttmp *map[string]interface{
 	}
 
 	//如果-仅有省份-敏感词-校验核对方法
-	if arearesult!="全国" && cityresult=="" {
-		sensitive_city := e.SensitiveCityData(qu.ObjToString((*j.Data)["detail"]),arearesult)
-		if sensitive_city !="" {
+	if arearesult != "全国" && cityresult == "" {
+		sensitive_city := e.SensitiveCityData(qu.ObjToString((*j.Data)["detail"]), arearesult)
+		if sensitive_city != "" {
 			(*resulttmp)["city"] = sensitive_city
 			(*resulttmp)["is_sensitive"] = 1
 		}
 	}
 
-
-
-
-
 }
 
 //jsondata中抽取城市
@@ -423,7 +415,7 @@ func (e *ExtractTask) NewGetCityByAreaCode(j *ju.Job, buyertel string) (province
 				if len(citytmp) == 1 { //对应多个city舍去
 					city = citytmp[0]
 					score := float64(5)
-					if areacode=="0371" {
+					if areacode == "0371" {
 						score = float64(4)
 					}
 					PCDScore(j, "city", city, score, true)
@@ -623,7 +615,7 @@ func (e *ExtractTask) NewGetCityByOthers(j *ju.Job, sm *SortMap, pscore, cscore,
 									}
 
 									//新增~特殊组情况下~津市高新区管委会~切词首"津市"~均未匹配到情况下
-									if jb_index==0 && len(dfull_citys) == 1 && len(j.FullAreaScore)==0 && len(j.SimAreaScore)==0{
+									if jb_index == 0 && len(dfull_citys) == 1 && len(j.FullAreaScore) == 0 && len(j.SimAreaScore) == 0 {
 										PCDScore(j, "district", dfull, 0, false)
 										PCDScore(j, "city", c.Name, 0, false)
 										PCDScore(j, "province", tmpPbrief, 0, false) //
@@ -957,24 +949,23 @@ func (e *ExtractTask) RemoveCD(finishP []string, j *ju.Job) {
 
 }
 
-
 //-新疆兵团映射-
-func(e *ExtractTask) CheckingXjbtCity(buyer string) (new_a,new_c,new_d string,ok bool){
-	buyer = strings.ReplaceAll(buyer,"新疆兵团","新疆生产建设兵团")
+func (e *ExtractTask) CheckingXjbtCity(buyer string) (new_a, new_c, new_d string, ok bool) {
+	buyer = strings.ReplaceAll(buyer, "新疆兵团", "新疆生产建设兵团")
 	ok = false
-	for _,info := range e.XjbtCityArr{
+	for _, info := range e.XjbtCityArr {
 		name := qu.ObjToString(info["name"])
 		alias := qu.ObjToString(info["alias"])
-		if strings.Contains(buyer,name) || strings.Contains(buyer,alias) {
+		if strings.Contains(buyer, name) || strings.Contains(buyer, alias) {
 			new_a = qu.ObjToString(info["area"])
 			new_c = qu.ObjToString(info["city"])
 			new_d = qu.ObjToString(info["district"])
 			ok = true
-			if res,ok := info["list"].([]interface{});ok {
+			if res, ok := info["list"].([]interface{}); ok {
 				list := qu.ObjArrToMapArr(res)
-				for _,c := range list {
+				for _, c := range list {
 					c_name := qu.ObjToString(c["name"])
-					if strings.Contains(buyer,name+c_name) || strings.Contains(buyer,alias+c_name) {
+					if strings.Contains(buyer, name+c_name) || strings.Contains(buyer, alias+c_name) {
 						new_a = qu.ObjToString(c["area"])
 						new_c = qu.ObjToString(c["city"])
 						new_d = qu.ObjToString(c["district"])
@@ -985,33 +976,31 @@ func(e *ExtractTask) CheckingXjbtCity(buyer string) (new_a,new_c,new_d string,ok
 			break
 		}
 	}
-	return new_a,new_c,new_d,ok
+	return new_a, new_c, new_d, ok
 }
 
-
-
 //敏感词识别~~~
-func(e *ExtractTask) SensitiveCityData(detail string, area string) string{
+func (e *ExtractTask) SensitiveCityData(detail string, area string) string {
 	//采用正文
-	detail = sensitiveReg.ReplaceAllString(detail,"")
+	detail = sensitiveReg.ReplaceAllString(detail, "")
 	//删除表格相关-文本
 	detail = TextAfterRemoveTable(detail)
 
 	sim_arr := e.SensitiveSimCity.FindAll(detail)
 	full_arr := e.SensitiveFullCity.FindAll(detail)
-	if len(full_arr)<3 {
-		for _,v := range full_arr{
+	if len(full_arr) < 3 {
+		for _, v := range full_arr {
 			if cityMap := e.CityFullMap[v]; cityMap != nil {
-				if cityMap.P.Brief==area {
+				if cityMap.P.Brief == area {
 					return cityMap.Name
 				}
 			}
 		}
 	}
-	if len(sim_arr)<3 {
-		for _,v := range sim_arr{
+	if len(sim_arr) < 3 {
+		for _, v := range sim_arr {
 			if cityMap := e.CityBriefMap[v]; cityMap != nil {
-				if cityMap.P.Brief==area && !strings.Contains(area,v) {
+				if cityMap.P.Brief == area && !strings.Contains(area, v) {
 					return cityMap.Name
 				}
 			}
@@ -1026,10 +1015,6 @@ func(e *ExtractTask) SensitiveCityData(detail string, area string) string{
 	return ""
 }
 
-
-
-
-
 //province,city,district干扰项减分
 //func PCDSubtractScore(e *ExtractTask, j *ju.Job, stype, text string, score int) {
 //	defer qu.Catch()

+ 64 - 61
src/jy/pretreated/analystep.go

@@ -6,21 +6,19 @@ package pretreated
 import (
 	"encoding/json"
 	"fmt"
+	"github.com/PuerkitoBio/goquery"
 	"jy/clear"
 	"jy/util"
 	qu "qfw/util"
 	"regexp"
 	"strings"
-
-	"github.com/PuerkitoBio/goquery"
 )
+
 //投标文件格式 技术评分明细表
 var yjReg *regexp.Regexp = regexp.MustCompile("(打分表|负责人|单位|个人|投标人|项目|企业)业绩|主要人员相关资料|唱标记录|标的名称|否决投标的?情况说明")
 var blTextReg *regexp.Regexp = regexp.MustCompile("(打分表|负责人|单位|个人|投标人|项目|企业)业绩|业绩奖项|主要人员相关资料|唱标记录|否决投标的?情况说明")
 var unblTextReg *regexp.Regexp = regexp.MustCompile("(项目业绩案例|类似项目业绩)")
 
-
-
 var preConReg1 = regexp.MustCompile("(第[一二三1-3]中标候选人)\n(业绩奖项)")
 var hisReg = regexp.MustCompile("(开标记录|开标记录及投标报价|类似业绩|历史业绩|填报项目业绩|[得评]+[审打]{0,2}分情况|无效标)[::\n]*.*?[\n]?(</td>)")
 var hisReg2 = regexp.MustCompile("(开标记录|[得评]+[审打]{0,2}分情况|无效标)[::\n]*.*?[\n]?(.*原因及其依据.*[::]?)?[\n]?.*?[\n]?(</tr>|</table>|</td>)")
@@ -29,26 +27,28 @@ var formattext = regexp.MustCompile("(投标总价)([0-9,.万元]*)")
 var formattext2 = regexp.MustCompile("中标单价.*(中标总价.*)")
 var formattext3 = regexp.MustCompile("(同类项目业绩、|[1-9].[0-9]包段划分)")
 
-
 //过滤多余字符
 var formattext4 = regexp.MustCompile("(中标金额[::])设计费用[::][0-9.万元,,]+施工费用[::][0-9.万元,,]+合计[::]([¥〇0-9\\.人民币零点壹贰叁肆伍陆柒捌玖拾佰仟万亿元圆角分整]+)")
 
 //特殊影响分包候选人抽取
 var formattext5 = regexp.MustCompile("投标报价[::]包件1[::][0-9.万元]+[,,]包件2[::][0-9.万元]+[,,]投标总价([::]+)([0-9.万元]+)")
-var formattext6  = regexp.MustCompile("(投标报价[::][0-9.]+)\n([万元]+)")
+var formattext6 = regexp.MustCompile("(投标报价[::][0-9.]+)\n([万元]+)")
 
-
-var formattext10  = regexp.MustCompile(".*包号\n.*\n.*供应商名称\n.*\n.*(成交|中标)金额\n(.*单位\n)?" +
+var formattext10 = regexp.MustCompile(".*包号\n.*\n.*供应商名称\n.*\n.*(成交|中标)金额\n(.*单位\n)?" +
 	"<td.*>(.*)\n(<td>\n)?.*\n<td.*>[\n]?(.*公司)\n.*\n<td.*>([0-9.,,万元]+)\n")
-var formattext11  = regexp.MustCompile("(项目预算)\n(第[一1](包|标段)[::])([0-9.万元人民币]+)\n" +
+var formattext11 = regexp.MustCompile("(项目预算)\n(第[一1](包|标段)[::])([0-9.万元人民币]+)\n" +
 	"(第[二2](包|标段)[::])([0-9.万元人民币]+)\n")
-var formattext12  = regexp.MustCompile("((成交|中标)价格|本期预算)\n[((]万元[))]\n([0-9.万元人民币]+)\n")
+var formattext12 = regexp.MustCompile("((成交|中标)价格|本期预算)\n[((]万元[))]\n([0-9.万元人民币]+)\n")
+
+//业绩相关~分割
+var formattext20 = regexp.MustCompile("(工程业绩|投标文件中填报的单位项目业绩名称)[::][\n]?1[、.].*\n2[、.].*\n(3[、.].*\n)?")
 
 //特殊文本提取-计算
-var formattext50  = regexp.MustCompile("主要标的数量[::]([0-9.]+)\n主要标的单价[::]([0-9.]+)\n合同金额[::].*\n履约期限")
+var formattext50 = regexp.MustCompile("主要标的数量[::]([0-9.]+)\n主要标的单价[::]([0-9.]+)\n合同金额[::].*\n履约期限")
 
 //特殊文本提取有效
-var formattext100  = regexp.MustCompile("项目编号.*\n项目名称.*\n招标单位.*\n招标代理.*\n中标单位.*\n项目编号.*\n总价[((]万元[))]([0-9.]+)")
+var formattext100 = regexp.MustCompile("项目编号.*\n项目名称.*\n招标单位.*\n招标代理.*\n中标单位.*\n项目编号.*\n总价[((]万元[))]([0-9.]+)")
+
 /*
 	项目编号JG2020-4278-003
 	项目名称株洲站改扩建工程(第五批)建管甲供物资(通信、信息专业)招标(ZZXX-02包件 安检仪等 WZ-2020-56)
@@ -64,42 +64,47 @@ var tablePackageWinnerReg = regexp.MustCompile("[\n]?(成交侯选人|第一中
 
 //特殊-爬虫文本-抽取单价数量-并计算
 func dealWithSpecStructToSpiderCode(text string) string {
-	text = formattext50.ReplaceAllString(text,"$1&&$2")
-	arr := strings.Split(text,"&&")
-	if len(arr)==2 {
+	text = formattext50.ReplaceAllString(text, "$1&&$2")
+	arr := strings.Split(text, "&&")
+	if len(arr) == 2 {
 		one := qu.Float64All(arr[0])
 		two := qu.Float64All(arr[1])
-		if one>0 && two>0 {
-			return fmt.Sprintf("\n合同金额:%f\n",one*two)
+		if one > 0 && two > 0 {
+			return fmt.Sprintf("\n合同金额:%f\n", one*two)
 		}
 	}
 	return ""
 }
+
 //对比前后候选人的有效性-true -为新
-func thanWinnerOrderEffective(old_order []map[string]interface{},new_order []map[string]interface{})bool {
-	if len(new_order)==0 || new_order == nil {
+func thanWinnerOrderEffective(old_order []map[string]interface{}, new_order []map[string]interface{}) bool {
+	if len(new_order) == 0 || new_order == nil {
 		return false
 	}
 	if len(old_order) == 0 || old_order == nil {
 		return true
 	}
-	old_info,new_info := old_order[0],new_order[0]
-	if qu.IntAll(old_info["sort"])>1 {return true}//排序比对
-	if qu.IntAll(new_info["sort"])>1 {return false}
+	old_info, new_info := old_order[0], new_order[0]
+	if qu.IntAll(old_info["sort"]) > 1 {
+		return true
+	} //排序比对
+	if qu.IntAll(new_info["sort"]) > 1 {
+		return false
+	}
 
 	//金额比对 -
-	isuse_1,isuse_2 := false,false
-	if old_vf, ok := old_info["price"].(float64); ok && old_vf>0.0 {
+	isuse_1, isuse_2 := false, false
+	if old_vf, ok := old_info["price"].(float64); ok && old_vf > 0.0 {
 		isuse_1 = true
-	}else {
-		if old_vs, ok := old_info["price"].(string); ok && old_vs!="" {
+	} else {
+		if old_vs, ok := old_info["price"].(string); ok && old_vs != "" {
 			isuse_1 = true
 		}
 	}
-	if new_vf, ok := new_info["price"].(float64); ok && new_vf>0.0 {
+	if new_vf, ok := new_info["price"].(float64); ok && new_vf > 0.0 {
 		isuse_2 = true
-	}else {
-		if new_vs, ok := new_info["price"].(string); ok && new_vs!="" {
+	} else {
+		if new_vs, ok := new_info["price"].(string); ok && new_vs != "" {
 			isuse_2 = true
 		}
 	}
@@ -113,8 +118,6 @@ func thanWinnerOrderEffective(old_order []map[string]interface{},new_order []map
 	return true
 }
 
-
-
 //分析方法
 func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 	con := job.Content
@@ -127,24 +130,26 @@ func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 
 	con = formattext.ReplaceAllString(con, "${1}:${2}")
 	con = formattext2.ReplaceAllString(con, "${1}")
-	con = formattext3.ReplaceAllString(con,"")
-	con = formattext4.ReplaceAllString(con,"\n${1}:${2}\n")
+	con = formattext3.ReplaceAllString(con, "")
+	con = formattext4.ReplaceAllString(con, "\n${1}:${2}\n")
 	//特殊格式-影响分包候选人抽取-替换
-	con = formattext5.ReplaceAllString(con,"中标金额:${2}\n")
-	con = formattext6.ReplaceAllString(con,"$1$2")
+	con = formattext5.ReplaceAllString(con, "中标金额:${2}\n")
+	con = formattext6.ReplaceAllString(con, "$1$2")
 	//改变特殊结构
-	con = formattext10.ReplaceAllString(con,"\n分包$3\n中标单位:$5 中标金额:$6\n")
-	con = formattext11.ReplaceAllString(con,"${1}\n${2}\n预算金额:${4}\n${5}\n预算金额:${7}\n${8}\n")
-	con = formattext12.ReplaceAllString(con,"\n${1}:${3}万元\n")
+	con = formattext10.ReplaceAllString(con, "\n分包$3\n中标单位:$5 中标金额:$6\n")
+	con = formattext11.ReplaceAllString(con, "${1}\n${2}\n预算金额:${4}\n${5}\n预算金额:${7}\n${8}\n")
+	con = formattext12.ReplaceAllString(con, "\n${1}:${3}万元\n")
 
+	//工程业绩描述影响抽取
+	con = formattext20.ReplaceAllString(con, "\n")
 
 	//指定爬虫-特殊结构-计算抽取
-	if codeSite=="a_zgzfcgw_zfcghtgg_new" {
-		str :=  formattext50.FindString(con)
-		if str!="" {
+	if codeSite == "a_zgzfcgw_zfcghtgg_new" {
+		str := formattext50.FindString(con)
+		if str != "" {
 			new_str := dealWithSpecStructToSpiderCode(str)
-			if new_str!="" {
-				con = new_str+con
+			if new_str != "" {
+				con = new_str + con
 			}
 		}
 	}
@@ -166,7 +171,7 @@ func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 	job.BlockPackage = map[string]*util.BlockPackage{}
 	//分块+处理每块kv
 	blockArrays, _ := DivideBlock(job.CategorySecond, con, 1, job.RuleBlock, isSite, codeSite)
-	if len(blockArrays) > 0 {                                                                  //有分块
+	if len(blockArrays) > 0 { //有分块
 		//从块里面找分包-文本
 		if !job.IsFile {
 			job.BlockPackage = FindPackageFromBlocks(&blockArrays, isSite, codeSite) //从块里面找分包
@@ -181,22 +186,22 @@ func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 			FindProjectCode(bl.Text, job) //匹配项目编号
 			//表格找分包相关---
 			isUnRulesTab := processTableInBlock(bl, job, isSite, codeSite) //处理表格
-			if isUnRulesTab { //是否不规则表格
+			if isUnRulesTab {                                              //是否不规则表格
 				job.IsUnRulesTab = isUnRulesTab
 			}
 
 			//新加 未分块table中未能解析到中标候选人,从正文中解析-全文匹配一次
-			if (job.Winnerorder == nil || len(job.Winnerorder) == 0 ) || len(job.Winnerorder) > 8 {
+			if (job.Winnerorder == nil || len(job.Winnerorder) == 0) || len(job.Winnerorder) > 8 {
 				//表格没有划分时候:-纯文本匹配
 				tmp_text := HtmlToText(bl.Text)
 				bl.Winnerorder = winnerOrderEntity.Find(tmp_text, true, 1, isSite, codeSite)
-				if thanWinnerOrderEffective(job.Winnerorder,bl.Winnerorder){
+				if thanWinnerOrderEffective(job.Winnerorder, bl.Winnerorder) {
 					job.Winnerorder = bl.Winnerorder
 				}
 			}
 
 			//无分包-附件-格式化文本处理-
-			if  (job.BlockPackage == nil || len(job.BlockPackage) == 0 ) &&
+			if (job.BlockPackage == nil || len(job.BlockPackage) == 0) &&
 				job.IsFile {
 				tmp_text := HtmlToText(bl.Text)
 				job.BlockPackage = FindPackageFromText(job.Title, tmp_text, isSite, codeSite)
@@ -237,7 +242,7 @@ func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 
 		bl.Text = HtmlToText(con)
 		FindProjectCode(bl.Text, job) //匹配项目编号 ~~ 清洗无效信息文本
-		if blTextReg.MatchString(bl.Text) && !unblTextReg.MatchString(bl.Text)   {
+		if blTextReg.MatchString(bl.Text) && !unblTextReg.MatchString(bl.Text) {
 			if strings.Index(bl.Text, "业绩") > 1 {
 				bl.Text = bl.Text[:strings.Index(bl.Text, "业绩")]
 			}
@@ -245,11 +250,10 @@ func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 		//特殊-指定处理-结构转化formattext100
 		if formattext100.MatchString(bl.Text) {
 			new_str := formattext100.FindString(bl.Text)
-			new_str = formattext100.ReplaceAllString(new_str,"$1")
-			bl.Text =fmt.Sprintf("中标金额:%s万元\n",new_str)+bl.Text
+			new_str = formattext100.ReplaceAllString(new_str, "$1")
+			bl.Text = fmt.Sprintf("中标金额:%s万元\n", new_str) + bl.Text
 		}
 
-
 		//调用kv解析库-处理detail
 		bl.Text = formatText(bl.Text, "all")
 		//处理 :
@@ -259,19 +263,19 @@ func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 		//新加 未分块table中未能解析到   中标候选人,从正文中解析
 		if job.Winnerorder == nil || len(job.Winnerorder) == 0 || len(job.Winnerorder) > 8 {
 			bl.Winnerorder = winnerOrderEntity.Find(bl.Text, true, 1, isSite, codeSite)
-			if thanWinnerOrderEffective(job.Winnerorder,bl.Winnerorder){
+			if thanWinnerOrderEffective(job.Winnerorder, bl.Winnerorder) {
 				job.Winnerorder = bl.Winnerorder
 			}
 		}
 
 		//如果表格查询分包-有分包-但是没有有效值的话 ,正文重新查找
-		if len(tabs) > 0 && job.BlockPackage!=nil {
+		if len(tabs) > 0 && job.BlockPackage != nil {
 			isUseful := false
-			for _,v := range job.BlockPackage{
-				p_winner :=v.Winner
-				p_budget :=v.Budget
-				p_bidamout :=v.Bidamount
-				if p_winner!=""||p_budget>float64(0)||p_bidamout>float64(0) {
+			for _, v := range job.BlockPackage {
+				p_winner := v.Winner
+				p_budget := v.Budget
+				p_bidamout := v.Bidamount
+				if p_winner != "" || p_budget > float64(0) || p_bidamout > float64(0) {
 					isUseful = true
 					break
 				}
@@ -284,7 +288,6 @@ func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 	}
 }
 
-
 func processTableInBlock(bl *util.Block, job *util.Job, isSite bool, codeSite string) bool {
 	//块中再查找表格(块,处理完把值赋到块)
 	//bl.Text = formatText(bl.Text, "biangeng")
@@ -293,7 +296,7 @@ func processTableInBlock(bl *util.Block, job *util.Job, isSite bool, codeSite st
 	for i, tab := range tabs {
 		job.HasTable = 1
 		tmptag := ""
-		if i == 0 && bl.Title != "" && bl.Title!="评标情况" && len(bl.Title) < 20 {
+		if i == 0 && bl.Title != "" && bl.Title != "评标情况" && len(bl.Title) < 20 {
 			tmptag = bl.Title
 		} else if tab.Nodes[0] != nil && tab.Nodes[0].PrevSibling != nil {
 			tmptag = strings.TrimSpace(tab.Nodes[0].PrevSibling.Data)

+ 129 - 142
src/jy/pretreated/analytable.go

@@ -109,9 +109,8 @@ var (
 	projectnameReg = regexp.MustCompile("((公开)?招标)*[((第]*[一二三四五六七八九十a-zA-Z0-9]+(标段|包|标|段)[))]*$")
 	MhSpilt        = regexp.MustCompile("[::]") //降低冒号权重
 	//指定字段且时间格式
-	UnTimeSpiltKey    = regexp.MustCompile("(招标文件获取截止时间|招标文件获取开始时间|报名截止时间|报名开始时间|投标文件递交开始时间|开工日期|竣工日期)")
-	UnTimeSpiltValue  = regexp.MustCompile("\\d{1,2}[::]\\d{1,2}")
-
+	UnTimeSpiltKey   = regexp.MustCompile("(招标文件获取截止时间|招标文件获取开始时间|报名截止时间|报名开始时间|投标文件递交开始时间|开工日期|竣工日期)")
+	UnTimeSpiltValue = regexp.MustCompile("\\d{1,2}[::]\\d{1,2}")
 
 	//识别采购单位联系人、联系电话、代理机构联系人、联系电话  -- 名称有异常
 	ContactInfoVagueReg = regexp.MustCompile("邮政编码|邮编|名称|(征求意见|报名审核购买)?((联系人?(及|和)?|办公|单位)?(((联系)?(电话|方式|号码)([//及]传真|及手机)?|手机)(号码)?|邮箱(地址)?|(详细)?(地(址|点)))|(联系|收料)(人(姓名)?|方式)|传真|电子邮件|(主要负责|项目(负责|联系)|经办)人)|采购方代表")
@@ -135,11 +134,10 @@ var (
 	WinnerOrderStr              = regexp.MustCompile(`(集团|公司|学校|中心|家具城|门诊|[大中小]+学|部|院|局|厂|店|所|队|社|室|厅|段|会|场|行)$`)
 	DoubtReg                    = regexp.MustCompile("(我中心|有(疑问|质疑|异议|意见)|(书面)?提出|不再受理|投诉|质疑|书面形式|监督|公示期(限)?)")
 
-
 	//新增-分包-表格-sortKV
-	budgetSortKVReg = regexp.MustCompile("(预算)")
+	budgetSortKVReg    = regexp.MustCompile("(预算)")
 	bidamountSortKVReg = regexp.MustCompile("(成交结果[((]万元[))])")
-	winnerSortKVReg = regexp.MustCompile("(投标人[((]供应商[))]名称)")
+	winnerSortKVReg    = regexp.MustCompile("(投标人[((]供应商[))]名称)")
 )
 
 //在解析时,判断表格元素是否隐藏
@@ -173,15 +171,15 @@ func CommonDataAnaly(k, tabletag, tabledesc string, v interface{}, isSite bool,
 	//先清理key
 	//u.Debug(1, k, v1)
 	//指定-key不清理  拦标价(费率或单价等)
-	k1:=""
+	k1 := ""
 	if !no_clear_key_reg.MatchString(k) {
 		k1 = ClearKey(k, 2)
 	}
 	//u.Debug(2, k)
 	//取标准key
 	if tabletag == "中标情况" {
-		if k1=="价格" {
-			k1="中标金额"
+		if k1 == "价格" {
+			k1 = "中标金额"
 		}
 	}
 	res := u.GetTags(k1, isSite, codeSite)
@@ -197,7 +195,7 @@ func CommonDataAnaly(k, tabletag, tabledesc string, v interface{}, isSite bool,
 	if len(res) > 0 {
 		for _, t1 := range res {
 			//降低冒号值的权重-不适合日期格式的数据
-			if MhSpilt.MatchString(v1) && !(UnTimeSpiltKey.MatchString(t1.Value) && UnTimeSpiltValue.MatchString(v1)){
+			if MhSpilt.MatchString(v1) && !(UnTimeSpiltKey.MatchString(t1.Value) && UnTimeSpiltValue.MatchString(v1)) {
 				t1.Weight -= 50
 			}
 			if winnerOrderAndBidResult.MatchString(tabletag) && t1.Value == "采购单位联系人" { //处理table中项目负责人
@@ -247,54 +245,56 @@ var djReg *regexp.Regexp = regexp.MustCompile("^单价")
 var hxrRex *regexp.Regexp = regexp.MustCompile("((成交|中标|中选)?候选人[弟|第][1-5一二三四五]名|[弟|第][1-5一二三四五][名]?(成交|中标|中选)?候选人)")
 
 //判断数组string 是否重复
-func isRepeatArrString(arr1,arr2 []string)bool{
+func isRepeatArrString(arr1, arr2 []string) bool {
 	is_r := true
-	for k,v := range arr1{
-		if v!=arr2[k] {
+	for k, v := range arr1 {
+		if v != arr2[k] {
 			is_r = false
 			break
 		}
 	}
 	return is_r
 }
+
 //中标金额-单位-同时存在-且万元-重构
 func isResetUnitAmountSortKV(table *Table) {
 	isUnitAmount := 0
 	for _, k := range table.SortKV.Keys {
 		v := table.SortKV.Map[k]
-		if new_v, ok := v.(string); ok&&(k=="中标金额"||k=="单位") {
-			if k=="单位" && new_v=="万元" {
+		if new_v, ok := v.(string); ok && (k == "中标金额" || k == "单位") {
+			if k == "单位" && new_v == "万元" {
 				isUnitAmount++
 			}
-			if k=="中标金额" && MoneyReg.MatchString(new_v) && !strings.Contains(new_v,"万") {
+			if k == "中标金额" && MoneyReg.MatchString(new_v) && !strings.Contains(new_v, "万") {
 				isUnitAmount++
 			}
 		}
 	}
-	if isUnitAmount>1 {
-		table.SortKV.Map["中标金额"] = qutil.ObjToString(table.SortKV.Map["中标金额"])+"万元"
+	if isUnitAmount > 1 {
+		table.SortKV.Map["中标金额"] = qutil.ObjToString(table.SortKV.Map["中标金额"]) + "万元"
 	}
 }
+
 //重置as~keys
-func resetAsKeysBidamount(as *SortMap){
-	keys ,values_data:= as.Keys,as.Map
-	if len(keys)==0 {
+func resetAsKeysBidamount(as *SortMap) {
+	keys, values_data := as.Keys, as.Map
+	if len(keys) == 0 {
 		return
 	}
-	k1,k2 := "投标报价(元)","经评审的投标价(元)"
-	value1,value2 := make([]string,0),make([]string,0)
+	k1, k2 := "投标报价(元)", "经评审的投标价(元)"
+	value1, value2 := make([]string, 0), make([]string, 0)
 	is_del := false
-	if arr, ok := values_data[k1].([]string); ok && len(arr)>0{
+	if arr, ok := values_data[k1].([]string); ok && len(arr) > 0 {
 		value1 = arr
-	}else {
+	} else {
 		return
 	}
-	if arr, ok := values_data[k2].([]string); ok && len(arr)>0{
+	if arr, ok := values_data[k2].([]string); ok && len(arr) > 0 {
 		value2 = arr
-	}else {
+	} else {
 		return
 	}
-	if len(value1)==len(value2) && len(value1)>0 {
+	if len(value1) == len(value2) && len(value1) > 0 {
 		tmp_value := value2[0]
 		price := winnerOrderEntity.clear("中标金额", tmp_value+GetMoneyUnit(k1, tmp_value))
 		if pricestr, _ := price.(string); len(pricestr) < 30 && len(pricestr) > 0 {
@@ -306,9 +306,6 @@ func resetAsKeysBidamount(as *SortMap){
 	}
 }
 
-
-
-
 //对解析后的表格的kv进行过滤
 func (table *Table) KVFilter(isSite bool, codeSite string) {
 	//1.标准化值查找
@@ -323,10 +320,6 @@ func (table *Table) KVFilter(isSite bool, codeSite string) {
 	//中标金额-单位-同时存在-且万元-重构
 	isResetUnitAmountSortKV(table)
 
-
-
-
-
 	//遍历table.sortkv,进行过滤处理,并放入标准化KV中,如果值是数组跳到下一步处理
 	pre_k := ""
 	for _, k := range table.SortKV.Keys {
@@ -350,17 +343,17 @@ func (table *Table) KVFilter(isSite bool, codeSite string) {
 			MergeKvTags(table.StandKV, kvTags)
 		} else {
 			//同一行表格-相同值的标签 可能含义重复~影响分包抽取~需要过滤
-			if k=="最高限价(元)" && pre_k == "项目预算(元)"{
+			if k == "最高限价(元)" && pre_k == "项目预算(元)" {
 				isE := false
-				if v_arr, ok := v.([]string); ok && len(v_arr)>1{
-					if pre_v_arr, ok := as.Map[pre_k].([]string); ok && len(pre_v_arr)==len(v_arr) && isRepeatArrString(v_arr,pre_v_arr) {
+				if v_arr, ok := v.([]string); ok && len(v_arr) > 1 {
+					if pre_v_arr, ok := as.Map[pre_k].([]string); ok && len(pre_v_arr) == len(v_arr) && isRepeatArrString(v_arr, pre_v_arr) {
 						isE = true
 					}
 				}
 				if !isE {
 					as.AddKey(k, v)
 				}
-			}else {
+			} else {
 				as.AddKey(k, v)
 			}
 		}
@@ -371,8 +364,6 @@ func (table *Table) KVFilter(isSite bool, codeSite string) {
 	//重置as~特殊金额~构建
 	resetAsKeysBidamount(as)
 
-
-
 	//处理值是数组的kv   放入标准化kv中 standKV //处理table.SortKV.value为数组的情况
 	table.sortKVArr(as, isSite, codeSite)
 
@@ -383,12 +374,12 @@ func (table *Table) KVFilter(isSite bool, codeSite string) {
 			if hxrRex.MatchString(k) {
 				v := table.SortKV.Map[k]
 				if new_v, ok := v.(string); ok && findCandidate2.MatchString(new_v) {
-					winsArr = append(winsArr,new_v)
-					sortsArr = append(sortsArr,k)
+					winsArr = append(winsArr, new_v)
+					sortsArr = append(sortsArr, k)
 				}
 			}
 		}
-		if len(winsArr)>1 {
+		if len(winsArr) > 1 {
 			as.AddKey("中标候选人名称", winsArr)
 			as.AddKey("中标候选人排序", sortsArr)
 			table.sortKVArr(as, isSite, codeSite)
@@ -457,6 +448,7 @@ func (table *Table) KVFilter(isSite bool, codeSite string) {
 
 var winMoneyReg *regexp.Regexp = regexp.MustCompile("(报价|投标价|投标总价|含税总价[((]元[))]|总金额)")
 var winNoMoneyReg *regexp.Regexp = regexp.MustCompile("(得分|时间|序号)")
+
 //处理table.SortKV.value为数组的情况
 func (table *Table) sortKVArr(as *SortMap, isSite bool, codeSite string) {
 	winnertag := iswinnertabletag.MatchString(table.Tag) && !nswinnertabletag.MatchString(table.Tag) //table标签
@@ -531,7 +523,7 @@ func (table *Table) sortKVArr(as *SortMap, isSite bool, codeSite string) {
 											}
 										} else if winMoneyReg.MatchString(k) && !winNoMoneyReg.MatchString(k) && len(tmpPrice[vsk]) == 0 {
 											kv = "中标金额"
-										}else { //验证val时如果数组中的第一条数据既不满足sort或者entname 判定此数组数据错误
+										} else { //验证val时如果数组中的第一条数据既不满足sort或者entname 判定此数组数据错误
 											break
 										}
 									}
@@ -630,7 +622,7 @@ func (table *Table) sortKVArr(as *SortMap, isSite bool, codeSite string) {
 				}
 			} else if vsss, ok := v.([]string); ok {
 				if (len(table.WinnerOrder) > 0 && table.WinnerOrder[0]["price"] == nil && len(vsss) == len(table.WinnerOrder)) ||
-					(len(table.WinnerOrder) > 0 && strings.Contains(k,"总报价") && len(vsss) == len(table.WinnerOrder)){
+					(len(table.WinnerOrder) > 0 && strings.Contains(k, "总报价") && len(vsss) == len(table.WinnerOrder)) {
 					kv := ""
 					if winMoneyReg.MatchString(k) && !winNoMoneyReg.MatchString(k) {
 						kv = "中标金额"
@@ -783,10 +775,10 @@ func (table *Table) MergerToTableresult() {
 	//遍历标准key到tableresult.sortkv中
 	for fieldKey, v := range table.StandKV {
 		for _, vv := range v {
-			if fieldKey=="项目周期"||fieldKey=="工期单位"||fieldKey=="工期时长" {
+			if fieldKey == "项目周期" || fieldKey == "工期单位" || fieldKey == "工期时长" {
 				dateStr := dateReg.FindString(vv.Key)
-				if dateStr !="" && !strings.Contains(vv.Value,dateStr) {
-					vv.Value = vv.Value+dateStr
+				if dateStr != "" && !strings.Contains(vv.Value, dateStr) {
+					vv.Value = vv.Value + dateStr
 				}
 			}
 			vv.Value = strings.Replace(vv.Value, "__", "", -1)
@@ -1065,7 +1057,7 @@ func (tn *Table) AnalyTables(contactFormat *u.ContactFormat, isSite bool, codeSi
 				table.extractPriceNumber()
 			}
 			res, _, _, _, _ := CheckCommon(table.Tag, "abandontable")
-			if !res {//调试
+			if !res { //调试
 				//过滤、标准化、合并kv,table.StandKV,table.StandKVWeight
 				table.KVFilter(isSite, codeSite)
 			}
@@ -1471,7 +1463,7 @@ func (table *Table) ComputeRowColIsKeyRation(isSite bool, codeSite string) {
 							ration1, _ := table.StartAndEndRation[ck].GetTDRation(td)
 							if !checkCompute[ck] {
 								checkCompute[ck] = true
-								if ration1 >= checkval && td.ColPos != 1  {
+								if ration1 >= checkval && td.ColPos != 1 {
 									for _, tr1 := range table.TRs {
 										for _, td1 := range tr1.TDs {
 											if td1.StartCol == td.StartCol {
@@ -1643,9 +1635,9 @@ func (table *Table) FindKV(isSite bool, codeSite string) {
 		//sort := 1
 		nextdirect, nextvdirect := 0, 0
 		//开始抽取
-		than_once_1,than_once_2 := false,false
+		than_once_1, than_once_2 := false, false
 		for tr_index, tr := range table.TRs {
-			if tr_index==7 {
+			if tr_index == 7 {
 				//fmt.Println("调试")
 			}
 			bcon = trSingleColumn(tr, bcon, table) //tr单列,是否丢弃内容
@@ -1660,8 +1652,8 @@ func (table *Table) FindKV(isSite bool, codeSite string) {
 					}
 				}
 				if numbh != 0 && numbh == len(tr.TDs) { //5e0d53ef0cf41612e0640495
-					if tr_index==0 {
-						than_once_1,than_once_2 = true,true
+					if tr_index == 0 {
+						than_once_1, than_once_2 = true, true
 					}
 					nextdirect, nextvdirect = 2, 1
 					continue
@@ -1679,12 +1671,12 @@ func (table *Table) FindKV(isSite bool, codeSite string) {
 					if !table.FindTdVal(td, direct, vdirect) { //table.FindTdVal()存储了table.SortKV
 						table.FindTdVal(td, vdirect, direct)
 					}
-					if than_once_1 && tr_index==1 {
-						table.FindTdVal(td, 1, 2)  //table.FindTdVal()存储了table.SortKV
+					if than_once_1 && tr_index == 1 {
+						table.FindTdVal(td, 1, 2) //table.FindTdVal()存储了table.SortKV
 						than_once_1 = false
 					}
-				}else {
-					if than_once_2 && tr_index==1 && td.BH && findCandidate.MatchString(td.Val){
+				} else {
+					if than_once_2 && tr_index == 1 && td.BH && findCandidate.MatchString(td.Val) {
 						table.FindTdVal(td, 1, 2) //特殊计算表头异常-情况
 					}
 				}
@@ -1924,17 +1916,13 @@ func GetBidSort(str string, n int) int {
 
 var cleardwReg *regexp.Regexp = regexp.MustCompile("[((]{1}\\d*[人元件个公斤户]/[人元件个公斤户][))]")
 var zbhxrReg *regexp.Regexp = regexp.MustCompile("(中标候选人|投标单位名称|候选人姓名)")
-var zbhxrSortReg_1 *regexp.Regexp = regexp.MustCompile("([第|弟][123一二三]名)")
+var zbhxrSortReg_1 *regexp.Regexp = regexp.MustCompile("^[第|弟][123一二三]名$")
 var zbhxrSortReg_2 *regexp.Regexp = regexp.MustCompile("^([123一二三])$")
-
 var zbhxrSortReg_3 *regexp.Regexp = regexp.MustCompile("^([123一二三])")
 
-
-
 var zbhxrSortNameReg *regexp.Regexp = regexp.MustCompile("(中标候选人[第|弟][123一二三]名)|[第|弟][123一二三]中标候选人")
 var zbhxrSecondReg *regexp.Regexp = regexp.MustCompile("(中标候选人[第|弟][2二]名)|[第|弟][2二]中标候选人")
 
-
 //查找每一个单元格的表头,调用FindNear
 func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
 	if td.Val == "" || strings.TrimSpace(td.Val) == "" {
@@ -1948,21 +1936,21 @@ func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
 		key := repSpace.ReplaceAllString(near.Val, "")
 
 		//临时去掉换行-进行判断
-		tmp_tdVal := strings.ReplaceAll(td.Val,"\n","")
+		tmp_tdVal := strings.ReplaceAll(td.Val, "\n", "")
 
 		if key == "名称" && near.StartCol == 0 && near.Rowspan > 0 {
 			new_key := ""
 			tr := table.TRs[:td.TR.RowPos]
-			if len(tr)>len(tr)-1 && len(tr)>0 {
+			if len(tr) > len(tr)-1 && len(tr) > 0 {
 				tds := tr[len(tr)-1].TDs
-				if len(tds)>td.EndCol && tds !=nil {
+				if len(tds) > td.EndCol && tds != nil {
 					td1 := tds[td.EndCol]
 					if zbhxrSecondReg.MatchString(td1.Val) {
 						new_key = td1.Val
 					}
 				}
 			}
-			if new_key=="" {
+			if new_key == "" {
 				for _, vn := range table.TRs[near.Rowspan-1].TDs {
 					if strings.Contains(vn.Val, "代理") {
 						key = "代理机构"
@@ -1975,53 +1963,57 @@ func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
 						break
 					}
 				}
-			}else {
+			} else {
 				key = new_key
 			}
-		} else if zbhxrReg.MatchString(key) && findCandidate2.MatchString(tmp_tdVal){
+		} else if zbhxrReg.MatchString(key) && findCandidate2.MatchString(tmp_tdVal) {
 			new_key := "中标单位"
 			tr_top := table.TRs[:td.TR.RowPos]
-			if len(tr_top)>len(tr_top)-1 && len(tr_top)>0{ //上临查询
+			if len(tr_top) > len(tr_top)-1 && len(tr_top) > 0 { //上临查询
 				tds := tr_top[len(tr_top)-1].TDs
-				if len(tds)>td.ColPos && tds !=nil && len(tds)== len(td.TR.TDs){
+				if len(tds) > td.ColPos && tds != nil && len(tds) == len(td.TR.TDs) {
 					td1 := tds[td.ColPos]
 					if zbhxrSortNameReg.MatchString(td1.Val) {
 						new_key = td1.Val
-					}else {
+					} else {
 						if zbhxrSortReg_1.MatchString(td1.Val) {
-							new_key = "中标候选人"+td1.Val
+							new_key = "中标候选人" + td1.Val
 						}
 					}
 				}
 			}
-			if new_key=="中标单位" { //最左临查询
+			if new_key == "中标单位" { //最左临查询
 				tr_left := table.TRs[:td.TR.RowPos+1]
 				tds_left := tr_left[len(tr_left)-1].TDs
-				if td.ColPos>0 {
+				if td.ColPos > 0 {
 					td1 := tds_left[0]
 					if zbhxrSortReg_2.MatchString(td1.Val) { //针对排名情况
-						new_key = "中标候选人第"+td1.Val+"名"
+						new_key = "中标候选人第" + td1.Val + "名"
+					} else {
+						if zbhxrSortReg_1.MatchString(td1.Val) {
+							new_key = "中标候选人" + td1.Val
+						}
 					}
 				}
 			}
-			if new_key!="中标单位" {
+			if new_key != "中标单位" {
 				td.Val = tmp_tdVal
 			}
 			key = new_key
-		} else if key == "投标人名称" ||  key == "单位名称" {//左临上临-拼接
+		} else if key == "投标人名称" || key == "单位名称" { //左临上临-拼接
 			tmpnewnear := table.FindNear(near, 1)
 			if tmpnewnear == nil {
 				tmpnewnear = table.FindNear(near, 2)
 			}
 			if tmpnewnear != nil {
-				if (table.Tag=="成交候选人" || table.Tag=="中标候选人") &&
+				if (table.Tag == "成交候选人" || table.Tag == "中标候选人") &&
 					zbhxrSortReg_1.MatchString(tmpnewnear.Val) {
-					key = "中选候选人"+tmpnewnear.Val
-				}else {
+					key = "中选候选人" + tmpnewnear.Val
+				} else {
 					if tmpnewnear.MustBH || tmpnewnear.BH {
-						if tmpnewnear.Val == "中标候选人情况" && zbhxrSortReg_3.MatchString(td.Val){
-							key = "中标候选人第"+zbhxrSortReg_3.FindString(td.Val)+"名"
-						}else {
+						if tmpnewnear.Val == "中标候选人情况" && zbhxrSortReg_3.MatchString(td.Val) {
+							key = "中标候选人第" + zbhxrSortReg_3.FindString(td.Val) + "名"
+						} else {
 							key = tmpnewnear.Val + near.Val
 						}
 					}
@@ -2029,7 +2021,6 @@ func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
 			}
 		}
 
-
 		if near.Val == "" {
 			key = fmtkey("k", near.TR.RowPos, near.ColPos)
 		}
@@ -2127,25 +2118,25 @@ func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
 					varrpos = len(vals) - 1
 				}
 			} else if vals, ok := val.(string); ok && vals != "" && td.Val != "" {
-				tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(vals, ""))//已存在的kv
+				tmapval := strings.TrimSpace(cleardwReg.ReplaceAllString(vals, "")) //已存在的kv
 				tmapvaltd := strings.TrimSpace(cleardwReg.ReplaceAllString(td.Val, ""))
 				if bvalfind {
-					if key=="中标单位" {//不能覆盖---
+					if key == "中标单位" { //不能覆盖---
 
-					}else {
+					} else {
 						if tmapvaltd == "" {
 							val = td.Val //vals + "__" + td.Val
 						} else {
 							val = tmapvaltd
 						}
 					}
-				} else{
-					if key=="中标单位" { //新增不能数组
+				} else {
+					if key == "中标单位" { //新增不能数组
 
-					}else {
-						if zbhxrSortNameReg.MatchString(key){
+					} else {
+						if zbhxrSortNameReg.MatchString(key) {
 							//特殊~不构建数组
-						}else {
+						} else {
 							tval := []string{}
 							if tmapval == "" {
 								tval = append(tval, vals)
@@ -2223,7 +2214,7 @@ func (table *Table) FindNear(td *TD, direct int) *TD {
 			for _, td1 := range tds {
 				if td1.StartRow <= td.StartRow && td1.EndRow >= td.EndRow && td1.EndCol+1 == td.StartCol {
 					//找到左临节点
-					if td1.BH || (zbhxrSortReg_1.MatchString(td1.Val)&&(table.Tag=="成交候选人"||table.Tag=="中标候选人")) {
+					if td1.BH || (zbhxrSortReg_1.MatchString(td1.Val) && (table.Tag == "成交候选人" || table.Tag == "中标候选人")) {
 						return td1
 					} else {
 						if td1.HeadTd != nil && td1.HeadTd.KVDirect == direct {
@@ -2251,11 +2242,11 @@ func (table *Table) FindNear(td *TD, direct int) *TD {
 						return tds[it-1]
 					} else if td1.HeadTd != nil && td1.HeadTd.KVDirect == direct && td.Colspan == td1.Colspan && td.Rowspan == td.Rowspan {
 						return td1.HeadTd
-					}else {
+					} else {
 
 					}
-				}else if len(td.TR.TDs)==len(tds) && i == len(tr)-1 && len(tds)>td.ColPos &&
-					it==td.ColPos && td1.EndRow+1 == td.StartRow {
+				} else if len(td.TR.TDs) == len(tds) && i == len(tr)-1 && len(tds) > td.ColPos &&
+					it == td.ColPos && td1.EndRow+1 == td.StartRow {
 					new_td := tds[td.ColPos]
 					if new_td.BH {
 						return new_td
@@ -2280,24 +2271,23 @@ func (tn *Table) GetTdByRCNo(row, col int) *TD {
 }
 
 //预算标签-不一定为分包
-func isUnRealBudgetBp(tnv []*u.Tag)bool {
-	if len(tnv)!=2 {
+func isUnRealBudgetBp(tnv []*u.Tag) bool {
+	if len(tnv) != 2 {
 		return false
 	}
-	key_1,key_2:= tnv[0].Key,tnv[1].Key
-	value_1,value_2 := tnv[0].Value,tnv[1].Value
-	if value_1!=value_2 {
-		if strings.Contains(key_1,"项目总投资")&&strings.Contains(key_2,"项目投资") {
+	key_1, key_2 := tnv[0].Key, tnv[1].Key
+	value_1, value_2 := tnv[0].Value, tnv[1].Value
+	if value_1 != value_2 {
+		if strings.Contains(key_1, "项目总投资") && strings.Contains(key_2, "项目投资") {
 			return true
 		}
-		if strings.Contains(key_2,"项目总投资")&&strings.Contains(key_1,"项目投资") {
+		if strings.Contains(key_2, "项目总投资") && strings.Contains(key_1, "项目投资") {
 			return true
 		}
 	}
 	return false
 }
 
-
 //判断表格是否是分包
 func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool, index []string) {
 	pac := 0             //包的数量
@@ -2365,18 +2355,18 @@ func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool,
 				if tn.BlockPackage.Map[v] == nil {
 					kv := u.NewJobKv()
 					for tnk, tnv := range tn.StandKV {
-						if nk >= len(tnv){
+						if nk >= len(tnv) {
 							continue
 						} else if len(index) == len(tnv) {
-							if tnk=="预算" && isUnRealBudgetBp(tnv) {
+							if tnk == "预算" && isUnRealBudgetBp(tnv) {
 								continue
 							}
-							if tnk=="预算"&& codeSite=="ha_zmdszfcgw_cgxx" && len(tnv)>1{
-								isEqErr,budget_v := false,""
-								for bk,bv:=range tnv {
-									if bk==0 {
+							if tnk == "预算" && codeSite == "ha_zmdszfcgw_cgxx" && len(tnv) > 1 {
+								isEqErr, budget_v := false, ""
+								for bk, bv := range tnv {
+									if bk == 0 {
 										budget_v = bv.Value
-									}else {
+									} else {
 										if budget_v != bv.Value {
 											isEqErr = true
 											break
@@ -2386,7 +2376,7 @@ func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool,
 								if isEqErr {
 									kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk])
 								}
-							}else {
+							} else {
 								kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk])
 							}
 						}
@@ -2429,17 +2419,25 @@ func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool,
 								bp.Text += fmt.Sprintf("%v:%v\n", kc, cv[0].Value)
 							}
 						}
-					}else { //新增 - 特殊情况 - 查找sortKV - 预算 - 中标金额 - 中标单位
-						for k,v := range tn.SortKV.Map {
+					} else { //新增 - 特殊情况 - 查找sortKV - 预算 - 中标金额 - 中标单位
+						for k, v := range tn.SortKV.Map {
 							if budgetSortKVReg.MatchString(k) {
 								if vs, ok := v.([]string); ok {
-									if len(index)==len(vs)  {
+									if len(index) == len(vs) {
 										moneys := clear.ObjToMoney([]interface{}{vs[nk], ""})
 										if len(moneys) > 0 {
 											if vf, ok := moneys[0].(float64); ok {
+												if !strings.Contains(vs[nk], "万") &&
+													strings.Contains(k, "万") {
+													vf = 10000.0 * vf
+												}
 												bp.Budget = vf
 												bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
 											} else if vi, ok := moneys[0].(int); ok {
+												if !strings.Contains(vs[nk], "万") &&
+													strings.Contains(k, "万") {
+													vi = 10000 * vi
+												}
 												bp.Budget = float64(vi)
 												bp.IsTrueBudget = moneys[len(moneys)-1].(bool)
 											}
@@ -2449,18 +2447,18 @@ func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool,
 							}
 							if bidamountSortKVReg.MatchString(k) {
 								if vs, ok := v.([]string); ok {
-									if len(index)==len(vs)  {
+									if len(index) == len(vs) {
 										moneys := clear.ObjToMoney([]interface{}{vs[nk], ""})
 										if len(moneys) > 0 {
 											if vf, ok := moneys[0].(float64); ok {
-												if !strings.Contains(vs[nk],"万") {
-													vf = 10000.0*vf
+												if !strings.Contains(vs[nk], "万") {
+													vf = 10000.0 * vf
 												}
 												bp.Bidamount = vf
 												bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
 											} else if vi, ok := moneys[0].(int); ok {
-												if !strings.Contains(vs[nk],"万") {
-													vi = 10000*vi
+												if !strings.Contains(vs[nk], "万") {
+													vi = 10000 * vi
 												}
 												bp.Bidamount = float64(vi)
 												bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
@@ -2696,9 +2694,9 @@ func foundPacBySortKV(tn *Table, val int, index []string, index_pos []int, keyEx
 					}
 				}
 			}
-			if k1=="标段" && len(index)==0 {
+			if k1 == "标段" && len(index) == 0 {
 				continue
-			}else {
+			} else {
 				break
 			}
 		}
@@ -2817,7 +2815,7 @@ func (tn *Table) assemblePackage(k1, v1, key string, isSite bool, codeSite strin
 						bp.IsTrueBidamount = moneys[len(moneys)-1].(bool)
 					}
 				}
-			}else if k3 == "中标单位" && bp.Winner =="" {
+			} else if k3 == "中标单位" && bp.Winner == "" {
 				new_str := qutil.ObjToString(winnerOrderEntity.clear("中标单位", v3[0].Value))
 				if new_str != "" && WinnerOrderStr.MatchString(new_str) {
 					bp.Winner = new_str
@@ -2844,12 +2842,10 @@ var saveThead = regexp.MustCompile("(?is)<thead>(.+?)</thead>")
 var clearpkg = regexp.MustCompile("(标示|标识)")
 var clearMoneyReg1 = regexp.MustCompile("(总成交金额:[0-9.]+)[\\s ]+([((]?万元[))]?)")
 
-
 func RepairCon(con string) string {
 	con = clearpkg.ReplaceAllString(con, "")
 
-
-	con = clearMoneyReg1.ReplaceAllString(con,"$1$2")
+	con = clearMoneyReg1.ReplaceAllString(con, "$1$2")
 	res := saveThead.FindAllStringSubmatch(con, 1)
 	th := ""
 	if len(res) == 1 && len(res[0]) == 2 {
@@ -3094,19 +3090,7 @@ L:
 				//采购人在联系人、电话后面的处理
 				tdAscFind = tn.hasIndexMap(thisTdKvs, &indexMap, tdAscFind)
 			}
-			//qutil.Debug(len(thisTdKvs), len(tr.TDs))
-			//			if len(thisTdKvs) >= 2 && len(tr.TDs) == 1 { //td中包含多个kv值 5d6b2aa2a5cb26b9b73e79d2
-			//				tmpIndexMap := map[int]string{}
-			//				start := 0
-			//				for _, td_kv := range thisTdKvs {
-			//					qutil.Debug(td_kv.Key)
-			//					for _, k := range HasOrderContactType(td_kv.Key) {
-			//						tmpIndexMap[start] = k
-			//						start++
-			//					}
-			//				}
-			//				indexMap = tmpIndexMap
-			//			}
+
 			prevKey := ""
 			oldIndexMapLength := len(indexMap)
 			thidTdIndex := td_index
@@ -3182,7 +3166,7 @@ L:
 					//myContactType
 
 					myContactType := indexMap[index]
-					if td_kv.Key=="地址" && strings.Contains(td_kv.PrevLine,"采购代理机构") {
+					if td_kv.Key == "地址" && strings.Contains(td_kv.PrevLine, "采购代理机构") {
 						myContactType = "代理机构"
 					}
 					//qutil.Debug(indexMap, index, myContactType)
@@ -3282,6 +3266,9 @@ func (tn *Table) asdFind(td_k string, matchCount int, weightMap map[string]map[s
 		if !ContactType[k].MatchString(td_k) { //没有匹配到采购单位,代理机构,中标单位
 			continue
 		}
+		if k == "采购单位" && td_k == "招标机构" {
+			continue
+		}
 		matchCount++
 		if weightMap[k] == nil {
 			weightMap[k] = map[string]interface{}{}

+ 15 - 8
src/jy/pretreated/colonkv.go

@@ -39,9 +39,11 @@ var (
 		"《": "》",
 		"<": ">",
 	}
-	//
 	PersonReg = regexp.MustCompile("[\u4e00-\u9fa5]{2,5}")
-	//
+
+	//验证冒号数量
+	colonNumReg = regexp.MustCompile("([::])")
+
 	TelMustReg            = regexp.MustCompile("^" + PhoneReg.String() + "$")
 	PersonMustReg         = regexp.MustCompile("^" + PersonReg.String() + "$")
 	AddressReg            = regexp.MustCompile("[省市县区路号楼]")
@@ -93,6 +95,11 @@ func (ce *ColonkvEntity) GetKvs(con, title string, from int) []*Kv {
 //处理正文
 func (ce *ColonkvEntity) processText(con string) string {
 	con = ce.divisionMoreKV(con) //一行多个冒号kv处理
+	//新增多个:
+	colonLen := colonNumReg.FindAllString(con, -1)
+	if len(colonLen) > 500 {
+		return con
+	}
 	for {
 		tmp := con
 		con = ce.divisionMoreKV(con)
@@ -817,10 +824,10 @@ func MergeKvTags(kvTags_1, kvTags_2 map[string][]*Tag) {
 	for k, v := range kvTags_2 {
 		for _, vv := range v {
 			value_vv := strings.TrimSpace(vv.Value)
-			if k=="项目周期"||k=="工期单位"||k=="工期时长" {
+			if k == "项目周期" || k == "工期单位" || k == "工期时长" {
 				dateStr := dateReg.FindString(vv.Key)
-				if dateStr !="" && !strings.Contains(value_vv,dateStr) {
-					vv.Value = value_vv+dateStr
+				if dateStr != "" && !strings.Contains(value_vv, dateStr) {
+					vv.Value = value_vv + dateStr
 				}
 			}
 			if value_vv == "" || vv.Key == vv.Value {
@@ -829,10 +836,10 @@ func MergeKvTags(kvTags_1, kvTags_2 map[string][]*Tag) {
 			isExists := false
 			for _, vvv := range kvTags_1[k] {
 				value_vvv := strings.TrimSpace(vvv.Value)
-				if k=="项目周期"||k=="工期单位"||k=="工期时长" {
+				if k == "项目周期" || k == "工期单位" || k == "工期时长" {
 					dateStr := dateReg.FindString(vvv.Key)
-					if dateStr !="" && !strings.Contains(value_vvv,dateStr) {
-						vvv.Value = value_vvv+dateStr
+					if dateStr != "" && !strings.Contains(value_vvv, dateStr) {
+						vvv.Value = value_vvv + dateStr
 					}
 				}
 				if (value_vvv == value_vv || TimeHM.ReplaceAllString(value_vvv, ReplTimeHM) == value_vv || value_vvv == TimeHM.ReplaceAllString(value_vv, ReplTimeHM)) && vvv.Weight == vv.Weight {

+ 5 - 1
src/jy/pretreated/division.go

@@ -293,6 +293,8 @@ func DivideBlock(tp, content string, from int, ruleBlock *util.RuleBlock, isSite
 		//分割标题 [和及]。。。 参与
 		splitTitles := ProcTitle(title)
 		blockText = mergetext(splitTitles, blockText)
+
+
 		block := &util.Block{
 			Index:  index,     //序号
 			Text:   blockText, //内容
@@ -374,7 +376,9 @@ func mergetext(titles []string, text string) string {
 		if len(lentexts) == 2 {
 			if strings.Contains(titles[i], lentexts[0]) {
 				tt += titles[i] + ":" + lentexts[1] + "\n"
-			}else if strings.Contains(titles[i], lentexts[0]) ||strings.Contains(titles[i], lentexts[0]){
+			}else if strings.Contains(strings.ReplaceAll(titles[i],"的",""), strings.ReplaceAll(lentexts[0],"的","")){
+				tt += titles[i] + ":" + lentexts[1] + "\n"
+			}else if strings.Contains(strings.ReplaceAll(titles[i],"联系地址","地址"), strings.ReplaceAll(lentexts[0],"联系地址","地址")){
 				tt += titles[i] + ":" + lentexts[1] + "\n"
 			}
 		}else {

+ 18 - 5
src/jy/pretreated/multipackage.go

@@ -21,8 +21,8 @@ var (
 	PreCon3 = regexp.MustCompile("(标段[一二三四五六七八九十0-9A-Za-z])[((].*[))][::]")
 
 	//提取分包标识
-	MultiReg = regexp.MustCompile("(([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-])+(包|标段|分标))[::]?|(?:^|\\n)([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-]+(包))|([第]?([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-]+)#?((子|合同|分|施工|监理)?(标段?|合同段|标包)))|(((子|合同|施工|监理|标包|标|包)(标|包段|项|段|组)?)[     ]*([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-]+))|((项目|包件)([一二三四五六七八九十1-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ]+))|((包组|包件)[::\\s]+([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-]+))|((施工|监理)(标段))[::\n]")
-	PreCon4 = regexp.MustCompile("([一二三四五六七八九十]标段[::¥0-9.]*(万元)?)[、]?")
+	MultiReg  = regexp.MustCompile("(([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-])+(包|标段|分标))[::]?|(?:^|\\n)([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-]+(包))|([第]?([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-]+)#?((子|合同|分|施工|监理)?(标段?|合同段|标包)))|(((子|合同|施工|监理|标包|标|包)(标|包段|项|段|组)?)[     ]*([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-]+))|((项目|包件)([一二三四五六七八九十1-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ]+))|((包组|包件)[::\\s]+([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ\\-]+))|((施工|监理)(标段))[::\n]")
+	PreCon4   = regexp.MustCompile("([一二三四五六七八九十]标段[::¥0-9.]*(万元)?)[、]?")
 	Precon4dw = regexp.MustCompile("(万元|元)")
 	//匹配到的包格式分类统计
 	keyregs = []map[*regexp.Regexp]int{
@@ -43,6 +43,9 @@ var (
 	//标题中含分包特征的标段一、二、三或包1、包2之类,根据
 	TitleReg     = regexp.MustCompile("([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ、\\-~至]+(子|合同|分|施工|监理|标)?[包标段][号段]?[、]?)+|((子|合同|分|施工|监理|标)?[包标段][号段]?[一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ、\\-~至]+[、]?)+|(子|合同|分|施工|监理|标)?[包标段][号段]?[a-zA-Z0-9]+[\\-~-至、](子|合同|分|施工|监理|标)?[包标段][号段]?[a-zA-Z0-9]+")
 	clearPkgFlag = regexp.MustCompile("^[\\-]+|[\\-]+$")
+
+	//无效冗余包名
+	cleanPkgName = regexp.MustCompile("^(1[-][23456789]包|一[-][二三四五六七八九]包)$")
 )
 
 //判断分包
@@ -57,8 +60,7 @@ func CheckMultiPackage(con string) (content string, m map[string][]string, b boo
 	con = PreCon3.ReplaceAllString(con, "${1}:")
 
 	//替换敏感词-分割
-	con  = replaceSenstiveReg1.ReplaceAllString(con,"$1\n$2")
-
+	con = replaceSenstiveReg1.ReplaceAllString(con, "$1\n$2")
 
 	//修改 \nX标段
 	res := MultiReg.FindAllStringSubmatch(con, -1)
@@ -94,7 +96,7 @@ func CheckMultiPackage(con string) (content string, m map[string][]string, b boo
 				vindex = 23
 			}
 
-			if k != "" && v[vindex] != "" &&  vindex!=5  {
+			if k != "" && v[vindex] != "" && vindex != 5 {
 				vindex += 1
 			}
 			if len(m[k]) == 0 && k != "" && v[vindex] != "" {
@@ -104,6 +106,17 @@ func CheckMultiPackage(con string) (content string, m map[string][]string, b boo
 				mindex[k] = index
 			}
 		}
+
+		//过滤无效包
+		new_m := map[string][]string{}
+		for k, v := range m {
+			if cleanPkgName.MatchString(k) {
+				continue
+			}
+			new_m[k] = v
+		}
+		m = new_m
+
 		if len(m) > 1 {
 			//对k优先级进行处理过滤
 			SEL := -1 //确定以哪种类型为标段标识,没有去判断v相同不相同,存在一定的误判!如 1:合同包1 1:包

+ 20 - 14
src/jy/pretreated/tablev2.go

@@ -42,17 +42,17 @@ type TableResult struct {
 //快速创建TableResult对象
 func NewTableResult(Id interface{}, Toptype, BlockTag, con string, Itype int, ruleBlock *u.RuleBlock) *TableResult {
 	return &TableResult{
-		Id:          Id,
-		Toptype:     Toptype,
-		Html:        con,
-		Itype:       Itype,
-		BlockTag:    BlockTag,
-		Tabs:        []*Table{},
-		GoqueryTabs: &goquery.Selection{},
-		PackageMap:  NewSortMap(),
-		KvTags:      map[string][]*u.Tag{},
-		RuleBlock:   ruleBlock,
-		isUnRulesTab:false,
+		Id:           Id,
+		Toptype:      Toptype,
+		Html:         con,
+		Itype:        Itype,
+		BlockTag:     BlockTag,
+		Tabs:         []*Table{},
+		GoqueryTabs:  &goquery.Selection{},
+		PackageMap:   NewSortMap(),
+		KvTags:       map[string][]*u.Tag{},
+		RuleBlock:    ruleBlock,
+		isUnRulesTab: false,
 	}
 }
 
@@ -165,8 +165,8 @@ func NewTD(Goquery *goquery.Selection, tr *TR, table *Table, isSite bool, codeSi
 	td.tdIsHb(tr, table, bsontable, isSite, codeSite)
 	bhead := false
 	if td.TR.RowPos == 0 { //第一行
-		no_head_b, _, _, _, _ :=CheckCommon(td.Val,"normalhead")
-		if  !no_head_b && utf8.RuneCountInString(td.Val) < 15 && td.Goquery.Closest("thead").Size() == 1 && !bsontable { //如果是thead确定为k值表头
+		no_head_b, _, _, _, _ := CheckCommon(td.Val, "normalhead")
+		if !no_head_b && utf8.RuneCountInString(td.Val) < 15 && td.Goquery.Closest("thead").Size() == 1 && !bsontable { //如果是thead确定为k值表头
 			bhead = true
 		}
 	}
@@ -303,6 +303,12 @@ func (td *TD) tdIsHb(tr *TR, table *Table, bsontable, isSite bool, codeSite stri
 		kvTitle = td.TR.TDs[len(td.TR.TDs)-1].Val
 	}
 	lenval := utf8.RuneCountInString(td.Val) //经过处理的td内容长度
+	//长度过长~截取~单元格内容
+	if lenval >= 30000 {
+		td.Val = td.Val[:30000]
+		td.Text = td.Text[:30000]
+		td.Html = td.Html[:30000]
+	}
 	ub := []*u.Block{}
 	//经过处理的td内容长度大于50,划块,分包
 	if lenval > 50 { //看是否划块
@@ -392,7 +398,7 @@ func (td *TD) tdIsHb(tr *TR, table *Table, bsontable, isSite bool, codeSite stri
 		if len(ub) > 0 {
 			blockPackage = FindPackageFromBlocks(&ub, isSite, codeSite) //从块里面找分包
 		} else {
-			if !excludeKey2.MatchString(td.Val) &&td.Val!="" {
+			if !excludeKey2.MatchString(td.Val) && td.Val != "" {
 				blockPackage = FindPackageFromText(kvTitle, td.Val, isSite, codeSite) //从正文里面找分包
 				if len(blockPackage) > 0 {
 					table.BPackage = true

+ 1 - 1
src/jy/util/ossclient.go

@@ -22,7 +22,7 @@ var (
 
 func InitOss(isTest bool) {
 	if isTest{
-		ossEndpoint = ossEndpointTest
+		ossEndpoint = ossEndpointTest   //测试服务器~阿里云
 	}
 	client, err := oss.New(ossEndpoint, ossAccessKeyId, ossAccessKeySecret)
 	if err != nil {

+ 10 - 37
src/main.go

@@ -13,8 +13,6 @@ import (
 	"net/http"
 	_ "net/http/pprof"
 	qu "qfw/util"
-	"qfw/util/elastic"
-	"qfw/util/redis"
 	"regexp"
 )
 
@@ -25,60 +23,35 @@ func init() {
 	qu.ReadConfig(&u.Config)
 	//抽取price和number相关
 	qu.ReadConfig("./res/pricenumber.json", &u.PriceNumberConfig)
-	/*
-		qu.ReadConfig("./res/brandrule.json", &util.BrandRules)
-		qu.ReadConfig("./res/goods.json", &util.GoodsConfig)
-		qu.ReadConfig("./res/brand.json", &util.BrandConfig)
-		初始化品牌和商品
-		util.InitBrand()
-		util.InitGoods()
-	*/
 	//初始化util
 	u.UtilInit()
-
-
-	//初始化redis
-	redis.InitRedisBySize(qu.ObjToString(u.Config["redis"]), 50, 30, 240)
-	//初始化elastic连接
-	elastic.InitElasticSize(qu.ObjToString(u.Config["elasticsearch"]), qu.IntAllDef(3, 30))
-	u.QYK_RedisName = qu.ObjToString(u.Config["redis_qyk"])
-	u.WinnerDB = qu.IntAll(u.Config["redis_winner_db"])
-	u.BuyerDB = qu.IntAll(u.Config["redis_buyer_db"])
-	u.AgencyDB = qu.IntAll(u.Config["redis_agency_db"])
-	
 }
 
 func main() {
-
-	extract.ExtractUdpUpdateMachine()	//节点上传~构建
-	extract.ExtractUdp() 				//udp通知抽取
-
+	extract.ExtractUdpUpdateMachine() //节点上传~构建
+	extract.ExtractUdp()              //udp通知抽取
 	go Router.Run(":" + qu.ObjToString(u.Config["port"]))
 	go log.Debug("启动..", qu.ObjToString(u.Config["port"]))
 
-	//testMain()
-
 	go func() {
 		http.ListenAndServe("localhost:10000", nil)
 	}()
 	lock := make(chan bool)
 	<-lock
-}
-
-
-
 
+}
 
 //验证规则
-func testMain()  {
-	text :=``
-	var letter_entity = regexp.MustCompile("")
-	if 	letter_entity.MatchString(text) {
+func testMain() {
+	con := ``
+	var formattext12 = regexp.MustCompile("(工程业绩|投标文件中填报的单位项目业绩名称)[::]1[、.].*\n2[、.].*\n(3[、.].*\n)?")
+	if formattext12.MatchString(con) {
 		log.Debug("匹配")
-	}else {
+		con = formattext12.ReplaceAllString(con, "\n")
+		log.Debug(con)
+	} else {
 		log.Debug("不匹配")
 	}
-	log.Debug(text)
 }
 
 

+ 77 - 13
src/mark

@@ -1,16 +1,4 @@
-//初始化redis
-redis.InitRedisBySize(qu.ObjToString(u.Config["redis"]), 50, 30, 240)
-//初始化elastic连接
-elastic.InitElasticSize(qu.ObjToString(u.Config["elasticsearch"]), qu.IntAllDef(3, 30))
-u.WinnerDB = qu.IntAll(u.Config["redis_winner_db"])
-u.BuyerDB = qu.IntAll(u.Config["redis_buyer_db"])
-u.AgencyDB = qu.IntAll(u.Config["redis_agency_db"])
-
-
-
-
-
-//目前线上
+//目前线上~web端
 {
     "port": "9080",
     "mgodb": "SJZY_RWExt_Other:SJZY%40E3X4t5O8th@172.17.145.163:27083",
@@ -73,3 +61,79 @@ u.AgencyDB = qu.IntAll(u.Config["redis_agency_db"])
     "deleteInstanceTimeHour": 1,
     "jsondata_extweight": 1
 }
+
+
+
+
+
+
+
+
+
+
+
+//抽取程序~线上配置
+{
+    "port": "9091",
+    "mgodb":"SJZY_RWExt_Other:SJZY%40E3X4t5O8th@172.17.145.163:27083,172.17.4.187:27082",
+    "dbsize": 3,
+    "dbname": "extract_2021",
+    "dbname_addrs": "mixdata",
+    "dbname_addrs_c": "address_new_2020",
+    "redis":"buyer=172.17.4.87:2679,winner=172.17.4.87:2679,agency=172.17.4.87:2679,qyk_redis=172.17.4.87:1479",
+    "redis_qyk": "qyk_redis",
+    "redis_winner_db": "1",
+    "redis_buyer_db": "2",
+    "redis_agency_db": "3",
+    "mergetable":"projectset",
+    "mergetablealias":"projectset_v1",
+    "saveresult": false,
+    "fieldsfind": false,
+    "saveblock":false,
+    "qualityaudit": false,
+    "filelength":50000,
+    "iscltlog":false,
+    "brandgoods":false,
+    "pricenumber":true,
+    "udptaskid": "5f2b9689e0f2ac0188851426",
+    "nextNode": [],
+    "udpport": "6601",
+    "udpmachine": {
+        "addr" : "172.17.4.238",
+        "port" : 6601,
+        "stype" : "extract_1",
+        "isuse" : 1
+    },
+    "esconfig": {},
+    "istest": false,
+    "isSaveTag":false,
+    "tomail":"zhengkun@topnet.net.cn",
+    "api":"http://172.17.145.179:19281/_send/_mail",
+    "deleteInstanceTimeHour":1,
+    "jsondata_extweight": 1
+}
+
+
+
+	/*
+		qu.ReadConfig("./res/brandrule.json", &util.BrandRules)
+		qu.ReadConfig("./res/goods.json", &util.GoodsConfig)
+		qu.ReadConfig("./res/brand.json", &util.BrandConfig)
+		初始化品牌和商品~
+		util.InitBrand()
+		util.InitGoods()
+	*/
+
+	//初始化redis elastic
+    	//redis.InitRedisBySize(qu.ObjToString(u.Config["redis"]), 50, 30, 240)
+    	//elastic.InitElasticSize(qu.ObjToString(u.Config["elasticsearch"]), qu.IntAllDef(3, 30))
+    	//u.QYK_RedisName = qu.ObjToString(u.Config["redis_qyk"])
+    	//u.WinnerDB = qu.IntAll(u.Config["redis_winner_db"])
+    	//u.BuyerDB = qu.IntAll(u.Config["redis_buyer_db"])
+    	//u.AgencyDB = qu.IntAll(u.Config["redis_agency_db"])
+
+
+
+
+
+    	SJZY_Rbid_ProG:SJZY%408Pro3gR79aM@172.17.145.163:27083,172.17.4.187:27082

+ 2 - 1
src/res/sv.txt

@@ -409394,4 +409394,5 @@ IT家园社区居委会 4 n
 冀南新区 4 n
 任泽区 4 n
 西洞庭管理区 4 n
-羊山新区 4 n
+羊山新区 4 n
+西咸新区 4 n

+ 1 - 1
src/res/tablev1.json

@@ -28,7 +28,7 @@
 		".{2,20}元整|[\\d]+万?元__",
 		".{4,}采购(项目)?__",
 		"(首选|第[一二三四五1-5])(顺序|推荐)?(承包|中标|候选|成交)?(候选)?(人|单位|供应商)__M",
-		"(招单价|无供应商报价|全部内容|计量单位|符合国家及行业标准的合格工程|二级建造师|公示信息|[甲乙丙]级)__",
+		"(招单价|无供应商报价|全部内容|计量单位|符合国家[和]行业|二级建造师|公示信息|[甲乙丙]级)__",
 		"^采购包[0-9]+$__"
 	],
 	"abandontable":[

+ 1 - 1
src/web/templates/admin/distribution.html

@@ -80,7 +80,7 @@ $(function () {
 			{ "data": "ip_nw","width":"17%",render:function(val,a,row,pos){
                 return val+"("+row.ip_ww+")"
             }},
-			{ "data": "AutoReleaseTime"},
+			{ "data": "AutoReleaseTime","width":"15%"},
             { "data": "Status"},
             { "data": "extstatus",render:function(val,a,row,pos){
                if(val){