Răsfoiți Sursa

Merge branch 'dev3.4' of http://192.168.3.207:10080/qmx/jy-data-extract into dev3.4

apple 5 ani în urmă
părinte
comite
788292f48c

+ 55 - 0
fullproject/src_v1/mgotool.go

@@ -192,3 +192,58 @@ func (m *MongodbSim) UpSertBulk(c string, doc ...[]map[string]interface{}) bool
 	}
 	return true
 }
+
+//批量插入
+func (m *MongodbSim) SaveBulk(c string, doc ...map[string]interface{}) bool {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	var writes []mongo.WriteModel
+	for _, d := range doc {
+		write := mongo.NewInsertOneModel()
+		write.SetDocument(d)
+		writes = append(writes, write)
+	}
+	_, e := coll.BulkWrite(m.Ctx, writes)
+	if e != nil {
+		log.Println("mgo savebulk error:", e.Error())
+		return false
+	}
+	return true
+}
+
+//保存
+func (m *MongodbSim) Save(c string, doc map[string]interface{}) interface{} {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	r, err := coll.InsertOne(m.Ctx, doc)
+	if err != nil {
+		return nil
+	}
+	return r.InsertedID
+}
+
+//更新by Id
+func (m *MongodbSim) UpdateById(c, id string, doc map[string]interface{}) bool {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	_, err := coll.UpdateOne(m.Ctx, map[string]interface{}{"_id": StringTOBsonId(id)}, doc)
+	if err != nil {
+		return false
+	}
+	return true
+}
+
+//删除
+func (m *MongodbSim) Delete(c, id string) int64 {
+	m.Open()
+	defer m.Close()
+	coll := m.C.Database(m.DbName).Collection(c)
+	r, err := coll.DeleteOne(m.Ctx, map[string]interface{}{"_id": StringTOBsonId(id)})
+	if err != nil {
+		return 0
+	}
+	return r.DeletedCount
+}

+ 19 - 19
src/jy/admin/rule.go

@@ -70,20 +70,20 @@ func init() {
 	Admin.POST("/rulelogic/use", RuleLogicUse)
 
 	//pkglogic
-	Admin.GET("/pkglogic", func(c *gin.Context) {
-		vid := c.Query("vid")
-		pid := c.Query("pid")
-		c.HTML(200, "pkg_logiclist.html", gin.H{"vid": vid, "pid": pid})
-	})
-	Admin.POST("/pkglogic/data", PkgLogicData)
-	Admin.POST("/pkglogic/save", PkgLogicSave)
-	Admin.POST("/pkgrulelogic/del", func(c *gin.Context) {
-		_id, _ := c.GetPostForm("_id")
-		b := Mgo.UpdateById("pkg_logic", _id, `{"$set":{"delete":true}}`)
-		go DelPkgLogicBack(_id)
-		c.JSON(200, gin.H{"rep": b})
-	})
-	Admin.POST("/pkglogic/use", PkgLogicUse)
+	//Admin.GET("/pkglogic", func(c *gin.Context) {
+	//	vid := c.Query("vid")
+	//	pid := c.Query("pid")
+	//	c.HTML(200, "pkg_logiclist.html", gin.H{"vid": vid, "pid": pid})
+	//})
+	//Admin.POST("/pkglogic/data", PkgLogicData)
+	//Admin.POST("/pkglogic/save", PkgLogicSave)
+	//Admin.POST("/pkgrulelogic/del", func(c *gin.Context) {
+	//	_id, _ := c.GetPostForm("_id")
+	//	b := Mgo.UpdateById("pkg_logic", _id, `{"$set":{"delete":true}}`)
+	//	go DelPkgLogicBack(_id)
+	//	c.JSON(200, gin.H{"rep": b})
+	//})
+	//Admin.POST("/pkglogic/use", PkgLogicUse)
 
 	Admin.GET("/logicpre", func(c *gin.Context) {
 		vid := c.Query("vid")
@@ -134,11 +134,11 @@ func init() {
 
 	Admin.GET("/pkglogicback", func(c *gin.Context) {
 		vid := c.Query("vid")
-		pid := c.Query("pid")
+		s_field := c.Query("s_field")
 		sid := c.Query("sid")
 		//查询属性字段
-		tmp, _ := Mgo.FindById("pkg_info", pid, `{"s_field":1}`)
-		c.HTML(200, "pkg_logicbacklist.html", gin.H{"vid": vid, "pid": pid, "sid": sid, "field": (*tmp)["s_field"]})
+		//tmp, _ := Mgo.FindById("pkg_info", pid, `{"s_field":1}`)
+		c.HTML(200, "pkg_logicbacklist.html", gin.H{"vid": vid, "sid": sid, "field": s_field,"s_field":s_field})
 	})
 	Admin.POST("/pkglogicback/data", PkgLogicBackData)
 	Admin.POST("/pkglogicback/save", PkgLogicBackSave)
@@ -379,10 +379,10 @@ func RuleLogicBackData(c *gin.Context) {
 }
 func PkgLogicBackData(c *gin.Context) {
 	vid, _ := c.GetPostForm("vid")
-	pid, _ := c.GetPostForm("pid")
+	s_field, _ := c.GetPostForm("s_field")
 	sid, _ := c.GetPostForm("sid")
 	data, _ := Mgo.Find("pkg_logicback", `{"sid":"`+sid+`","delete":false}`, `{"_id":-1}`, nil, false, -1, -1)
-	c.JSON(200, gin.H{"data": data, "vid": vid, "pid": pid, "sid": sid})
+	c.JSON(200, gin.H{"data": data, "vid": vid, "s_field": s_field, "sid": sid})
 }
 func RuleLogicBackSave(c *gin.Context) {
 	data := GetPostForm(c)

+ 1 - 0
src/jy/admin/rulecheck.go

@@ -324,6 +324,7 @@ func checkBackScript(table, code, name, version, infoid, script string, alone bo
 	e.TaskInfo = &extract.TaskInfo{Version: qu.ObjToString((*vsion)["s_version"]), VersionId: qu.BsonIdToSId((*vsion)["_id"]), TestLua: true}
 	e.InitSite()
 	e.InitRulePres()
+	e.InitPkgCore()
 	e.InitRuleBacks(false)
 	e.InitRuleBacks(true)
 	e.InitRuleCore(false)

+ 55 - 0
src/jy/admin/version.go

@@ -262,6 +262,17 @@ func init() {
 		//b := Mgo.Del("versioninfo", `{"_id":"`+_id+`"}`)
 		c.JSON(200, gin.H{"rep": b})
 	})
+
+	Admin.GET("/version/pkglogicore", func(c *gin.Context) {
+		vid := c.Query("vid")
+		s_field := c.Query("s_field")
+		sid := c.Query("sid")
+		c.HTML(200, "pkg_logicore.html", gin.H{"vid": vid, "sid": sid, "field": s_field})
+	})
+	Admin.POST("/version/pkglogicore/data", PkgRuleLogicCoreData)
+	Admin.POST("/version/pkglogicore/save", PkgRuleLogicCoreSave)
+	Admin.POST("/version/pkglogicore/del", PkgRuleLogicCoreDel)
+	Admin.POST("/version/pkglogicore/use", PkgRuleLogicCoreUse)
 	//分块配置
 	Admin.GET("/version/blockinfo", func(c *gin.Context) {
 		vid := c.Query("vid")
@@ -789,3 +800,47 @@ func getCode(code string) string {
 	tmp := tmps[:len(tmps)-1]
 	return strings.Join(tmp, "_")
 }
+func PkgRuleLogicCoreData(c *gin.Context) {
+	vid, _ := c.GetPostForm("vid")
+	sid, _ := c.GetPostForm("sid")
+	s_field, _ := c.GetPostForm("s_field")
+	data, _ := Mgo.Find("pkg_logicore", `{"sid":"`+sid+`","delete":false}`, `{"_id":-1}`, nil, false, -1, -1)
+	c.JSON(200, gin.H{"data": data, "vid": vid, "s_field": s_field, "sid": sid})
+}
+func PkgRuleLogicCoreSave(c *gin.Context) {
+	data := GetPostForm(c)
+	_id, _ := c.GetPostForm("_id")
+	b := false
+	if _id == "" {
+		data["l_createtime"] = time.Now().Unix()
+		data["s_username"] = sessions.Default(c).Get("username")
+		data["delete"] = false
+		s_type := data["s_type"]
+		code := ""
+		if s_type == "0" { //抽取逻辑正则
+			code = util.GetSyncIndex(E_CE)
+		} else { //抽取逻辑脚本
+			code = util.GetSyncIndex(E_CL)
+		}
+		data["s_code"] = code
+		b = Mgo.Save("pkg_logicore", data) != ""
+	} else {
+		data["l_lasttime"] = time.Now().Unix()
+		b = Mgo.Update("pkg_logicore", `{"_id":"`+_id+`"}`, map[string]interface{}{
+			"$set": data,
+		}, true, false)
+	}
+	c.JSON(200, gin.H{"rep": b})
+}
+func PkgRuleLogicCoreDel(c *gin.Context) {
+	_id, _ := c.GetPostForm("_id")
+	//b := Mgo.Del("rule_logicore", `{"_id":"`+_id+`"}`)
+	b := Mgo.UpdateById("pkg_logicore", _id, `{"$set":{"delete":true}}`)
+	c.JSON(200, gin.H{"rep": b})
+}
+func PkgRuleLogicCoreUse(c *gin.Context) {
+	_id, _ := c.GetPostForm("_id")
+	isuse, _ := c.GetPostForm("isuse")
+	b := Mgo.UpdateById("pkg_logicore", _id, `{"$set":{"isuse":`+isuse+`}}`)
+	c.JSON(200, gin.H{"rep": b})
+}

+ 1 - 0
src/jy/extract/exportask.go

@@ -63,6 +63,7 @@ func extractAndExport(v string, t map[string]interface{}) {
 	e.InitClearFn(true)
 	e.InfoTypeList()
 	e.InitBlockRule()
+	e.InitPkgCore()
 	//品牌抽取是否开启
 	ju.IsBrandGoods = ju.Config["brandgoods"].(bool)
 

+ 61 - 32
src/jy/extract/extpackage.go

@@ -7,34 +7,41 @@ import (
 	"log"
 	qu "qfw/util"
 	"reflect"
+	"regexp"
 	"sort"
 )
 
-func pkvdata(pkg *ju.BlockPackage, sonJobResult *map[string]interface{}, e *ExtractTask,isSite bool,codeSite string) {
+func pkvdata(pkg *ju.BlockPackage, sonJobResult *map[string]interface{}, e *ExtractTask, isSite bool, codeSite string) {
 
 	if pkg.ColonKV != nil {
-		kvparse(pkg.ColonKV,  e, sonJobResult,isSite,codeSite)
+		kvparse(pkg.ColonKV, e, sonJobResult, isSite, codeSite)
 	}
 	if pkg.TableKV != nil {
-		kvparse(pkg.TableKV,  e, sonJobResult,isSite,codeSite)
+		kvparse(pkg.TableKV, e, sonJobResult, isSite, codeSite)
 	}
 	if pkg.SpaceKV != nil {
-		kvparse(pkg.SpaceKV,  e, sonJobResult,isSite,codeSite)
+		kvparse(pkg.SpaceKV, e, sonJobResult, isSite, codeSite)
 	}
 }
 
-func kvparse(p *ju.JobKv,  e *ExtractTask, sonJobResult *map[string]interface{},isSite bool,codeSite string) {
+func kvparse(p *ju.JobKv, e *ExtractTask, sonJobResult *map[string]interface{}, isSite bool, codeSite string) {
 	if p != nil {
 		for pk, pv2 := range p.KvTags {
 			if len(pv2) > 1 && !(pk == "预算" || pk == "中标金额") {
 				tmp := []*ju.Tag{}
 				var tmpindex, tmpweight int = -9999, -9999
 				for ii, vv := range pv2 {
+					if pk == "中标单位" && regexp.MustCompile("[0-9.元人¥$]").MatchString(vv.Value) {
+						continue
+					}
 					if tmpweight < vv.Weight {
 						tmpindex = ii
 						tmpweight = vv.Weight
 					}
 				}
+				if tmpindex == -9999 {
+					continue
+				}
 				tmp = append(tmp, pv2[tmpindex])
 				p.KvTags[pk] = tmp
 			}
@@ -43,9 +50,9 @@ func kvparse(p *ju.JobKv,  e *ExtractTask, sonJobResult *map[string]interface{},
 			if len(pv) == 0 {
 				continue
 			}
-			tags := ju.GetTags(pk,isSite,codeSite)
+			tags := ju.GetTags(pk, isSite, codeSite)
 			if tags.Len() > 0 {
-				if ((*sonJobResult)["name"]  == nil || (*sonJobResult)["name"] == "")&& tags[0].Key == "项目名称"{
+				if ((*sonJobResult)["name"] == nil || (*sonJobResult)["name"] == "") && tags[0].Key == "项目名称" {
 					(*sonJobResult)["name"] = pv[0].Value
 				}
 				if qu.Float64All((*sonJobResult)["budget"]) == 0 && tags[0].Key == "预算" {
@@ -64,7 +71,7 @@ func kvparse(p *ju.JobKv,  e *ExtractTask, sonJobResult *map[string]interface{},
 					(*sonJobResult)["bidamount"] = data[0]
 					continue
 				}
-				if ((*sonJobResult)["winner"] == nil || (*sonJobResult)["winner"] == "" )&& tags[0].Key == "中标单位"{
+				if ((*sonJobResult)["winner"] == nil || (*sonJobResult)["winner"] == "") && tags[0].Key == "中标单位" {
 					(*sonJobResult)["winner"] = pv[0].Value
 				}
 
@@ -77,12 +84,24 @@ func kvparse(p *ju.JobKv,  e *ExtractTask, sonJobResult *map[string]interface{},
 }
 
 //处理分包信息
-func PackageDetail(j *ju.Job, e *ExtractTask,isSite bool,codeSite string) {
+func PackageDetail(j *ju.Job, e *ExtractTask, isSite bool, codeSite string) {
 	qu.Try(func() {
 		if len(j.BlockPackage) > 0 {
+			for _, ev := range e.PkgRuleCores {
+				for _, eve := range ev.RuleCores {
+					if !eve.IsLua {
+						ExtRuleCoreByPkgReg(j, eve, e) // 分包正则抽取   预算   中标单位 中标价 成交状态
+					}
+				}
+				for _, evb := range ev.RuleBacks {
+					if !evb.IsLua {
+						ExtRegBackPkg(j, evb) // 分包正则清理  中标单位 成交状态   内容 名称
+					}
+				}
+			}
 			tmpkeys := []string{}
 			for k, _ := range j.BlockPackage {
-				if k == ""{
+				if k == "" {
 					continue
 				}
 				tmpkeys = append(tmpkeys, k)
@@ -90,7 +109,7 @@ func PackageDetail(j *ju.Job, e *ExtractTask,isSite bool,codeSite string) {
 			sort.Strings(tmpkeys)
 			packageResult := map[string]map[string]interface{}{}
 			//packagenum := len(j.BlockPackage)
-			for i, pkName := range tmpkeys {
+			for _, pkName := range tmpkeys {
 				pkg, ok := j.BlockPackage[pkName]
 				if !ok {
 					continue
@@ -103,36 +122,38 @@ func PackageDetail(j *ju.Job, e *ExtractTask,isSite bool,codeSite string) {
 					sonJobResult["text"] = pkg.Text
 					sonJobResult["budget"] = pkg.Budget
 					sonJobResult["bidamount"] = pkg.Bidamount
-					wins := make([]map[string]interface{}, 0)
 					if pkg.Winner == "" && len(j.Winnerorder) > 0 {
 						if sonJobResult["winnerorder"] == nil {
-							for _, tv := range j.Winnerorder {
-									if tv["type"].(int) == i{
-										wins = append(wins, tv)
-									}
+							sonJobResult["winnerorder"] = j.Winnerorder
+							if sonJobResult["bidamount"].(float64) <= 0 {
+								sonJobResult["bidamount"] = qu.Float64All(j.Winnerorder[0]["price"])
+							}
+							if sonJobResult["winner"] == "" {
+								sonJobResult["winner"] = j.Winnerorder[0]["entname"]
 							}
-							sonJobResult["winnerorder"] = wins
-						}
-						if len(wins) >0{
-							sonJobResult["bidamount"] = wins[0]["price"]
-							sonJobResult["winner"] = wins[0]["entname"]
 						}
 					} else {
 						if len(j.Winnerorder) > 0 {
-							sonJobResult["bidamount"] = j.Winnerorder[0]["price"]
-							sonJobResult["winner"] = wins[0]["entname"]
+							sonJobResult["bidamount"] = qu.Float64All(j.Winnerorder[0]["price"])
+							sonJobResult["winner"] = j.Winnerorder[0]["entname"]
+						}
+						if len(pkg.WinnerOrder) > 0 {
+							sonJobResult["winnerorder"] = pkg.WinnerOrder
+							sonJobResult["winner"] = pkg.WinnerOrder[0]["entname"]
+						}
+						if sonJobResult["winner"] == nil || sonJobResult["winner"] == "" {
+							sonJobResult["winner"] = pkg.Winner
 						}
-						sonJobResult["winnerorder"] = pkg.WinnerOrder
 					}
-					pkvdata(pkg, &sonJobResult, e,isSite,codeSite)
+					pkvdata(pkg, &sonJobResult, e, isSite, codeSite)
 
 					sonJobResult["type"] = pkg.Type
-					if len(tmpkeys) == 1{
-						if qu.Float64All(sonJobResult["budget"])==0{
-							for _,bv := range j.Block{
-								kvparse(bv.ColonKV,e,&sonJobResult,isSite,codeSite)
-								kvparse(bv.TableKV,e,&sonJobResult,isSite,codeSite)
-								kvparse(bv.SpaceKV,e,&sonJobResult,isSite,codeSite)
+					if len(tmpkeys) == 1 {
+						if qu.Float64All(sonJobResult["budget"]) == 0 {
+							for _, bv := range j.Block {
+								kvparse(bv.ColonKV, e, &sonJobResult, isSite, codeSite)
+								kvparse(bv.TableKV, e, &sonJobResult, isSite, codeSite)
+								kvparse(bv.SpaceKV, e, &sonJobResult, isSite, codeSite)
 							}
 						}
 					}
@@ -248,12 +269,20 @@ func PackageDetail(j *ju.Job, e *ExtractTask,isSite bool,codeSite string) {
 				//log.Println(pkName, sonJobResult)
 				sonJobResult["clear"] = clearmap
 				packageResult[pkName] = sonJobResult
+
 			}
 			if len(packageResult) > 0 {
 				j.PackageInfo = packageResult
+				if len(j.Result["winner"]) == 0 {
+					tmpsss := []*ju.ExtField{}
+					for k, v := range packageResult {
+						tmpsss = append(tmpsss, &ju.ExtField{Field: "winner", ExtFrom: "j.PackageInfo." + k + ".winner", Value: v["winner"], Weight: -999})
+					}
+					j.Result["winner"] = tmpsss
+				}
 			}
 		}
-		extRegBackPack(j, e)
+		//extRegBackPack(j, e)
 	}, func(err interface{}) {
 		log.Println("PackageDetail err", err)
 	})

+ 168 - 0
src/jy/extract/extract.go

@@ -847,6 +847,158 @@ func ExtRuleCoreByReg(extfrom string, doc map[string]interface{}, j *ju.Job, in
 	}
 }
 
+//pkg抽取-规则-正则
+func ExtRuleCoreByPkgReg(j *ju.Job, in *RegLuaInfo, e *ExtractTask) {
+	defer qu.Catch()
+	//根据field配置项目,是否抽取。例如:废标、流标等跳过,
+	b := IsExtract(in.Field, j.Title, j.Content)
+	if !b {
+		return
+	}
+	//块抽取
+	if in.Field != "" {
+		for k, vbpkg := range j.BlockPackage {
+			rep := map[string]string{}
+			if in.RegCore.Bextract { //正则是两部分的,可以直接抽取的(含下划线)
+				if !((in.Field == "budget" && vbpkg.Budget > 0) || (in.Field == "bidamount" && vbpkg.Bidamount > 0) ||
+					(in.Field == "winner" && vbpkg.Winner == "") || (in.Field == "bidstatus" && vbpkg.BidStatus == "") ||
+					(in.Field == "projectname" && vbpkg.Name == "")) {
+					continue
+				}
+				//处理正负数修正
+				ptmp := strings.Split(in.RuleText, "#")
+				sign := 0
+				if len(ptmp) == 2 {
+					if ptmp[1] == "正" {
+						sign = 1
+					} else if ptmp[1] == "负" {
+						sign = -1
+					}
+				}
+				tmp := strings.Split(ptmp[0], "__")
+				if len(tmp) == 2 {
+					epos := strings.Split(tmp[1], ",")
+					posm := map[string]int{}
+					for _, v := range epos {
+						ks := strings.Split(v, ":")
+						if len(ks) == 2 { //(.*)招标公告(.*)__2:projectname,4:area
+							posm[ks[1]] = qu.IntAll(ks[0])
+						} else {
+							posm[in.Field] = qu.IntAll(ks[0])
+						}
+					}
+					var pattern string
+					if strings.Contains(tmp[0], "\\u") {
+						tmp[0] = strings.Replace(tmp[0], "\\", "\\\\", -1)
+						tmp[0] = strings.Replace(tmp[0], "\\\\u", "\\u", -1)
+						pattern, _ = strconv.Unquote(`"` + tmp[0] + `"`)
+					} else {
+						pattern = tmp[0]
+					}
+					//log.Debug("pattern", pattern)
+					//fmt.Println(text)
+					reg := regexp.MustCompile(pattern)
+					apos := reg.FindAllStringSubmatchIndex(vbpkg.Text, -1)
+					for i, _ := range apos {
+						pos := apos[i]
+						for k, p := range posm {
+							if len(pos) > p {
+								if pos[p] == -1 || pos[p+1] == -1 {
+									continue
+								}
+								val := vbpkg.Text[pos[p]:pos[p+1]]
+								if string(val) == "" {
+									continue
+								}
+								if sign == -1 {
+									rep[k+"_"+fmt.Sprint(i)] = "-" + val
+								} else {
+									rep[k+"_"+fmt.Sprint(i)] = val
+								}
+							}
+						}
+					}
+					//fmt.Println(text)
+					for i := 0; i < len(apos); i++ {
+						if strings.TrimSpace(rep[in.Field+"_"+fmt.Sprint(i)]) != "" {
+							if in.Field == "budget" && vbpkg.Budget <= 0 {
+								lock.Lock()
+								cfn := e.ClearFn[in.Field]
+								lock.Unlock()
+								data := clear.DoClearFn(cfn, []interface{}{strings.TrimSpace(rep[in.Field+"_"+fmt.Sprint(i)]), j.Content})
+								j.BlockPackage[k].Budget = qu.Float64All(data[0])
+								break
+							} else if in.Field == "bidamount" && vbpkg.Bidamount <= 0 {
+								lock.Lock()
+								cfn := e.ClearFn[in.Field]
+								lock.Unlock()
+								data := clear.DoClearFn(cfn, []interface{}{strings.TrimSpace(rep[in.Field+"_"+fmt.Sprint(i)]), j.Content})
+								j.BlockPackage[k].Bidamount = qu.Float64All(data[0])
+								break
+							} else if in.Field == "winner" {
+								if j.BlockPackage[k].Winner == "" {
+									j.BlockPackage[k].Winner = rep[in.Field+"_"+fmt.Sprint(i)]
+									break
+								}
+							} else if in.Field == "bidstatus" {
+								if j.BlockPackage[k].BidStatus == "" {
+									j.BlockPackage[k].BidStatus = rep[in.Field+"_"+fmt.Sprint(i)]
+									break
+								}
+							} else if in.Field == "projectname" {
+								if j.BlockPackage[k].Name == "" {
+									j.BlockPackage[k].Name = rep[in.Field+"_"+fmt.Sprint(i)]
+									break
+								}
+							}
+						}
+					}
+				}
+			} else {
+				pos := in.RegCore.Reg.FindStringIndex(vbpkg.Text)
+				val := ""
+				if len(pos) == 2 {
+					//"text" = "text"[pos[1]:]
+					val = "text"[pos[1]:]
+					rs := regexp.MustCompile("[^\r\n\t]+")
+					tmp := rs.FindAllString("text", -1)
+					if len(tmp) > 0 {
+						val = tmp[0]
+					}
+				}
+				if val != "" {
+					if in.Field == "budget" && vbpkg.Budget <= 0 {
+						lock.Lock()
+						cfn := e.ClearFn[in.Field]
+						lock.Unlock()
+						data := clear.DoClearFn(cfn, []interface{}{val, j.Content})
+						j.BlockPackage[k].Budget = qu.Float64All(data[0])
+						break
+					}
+					if in.Field == "bidamount" && vbpkg.Bidamount <= 0 {
+						lock.Lock()
+						cfn := e.ClearFn[in.Field]
+						lock.Unlock()
+						data := clear.DoClearFn(cfn, []interface{}{val, j.Content})
+						j.BlockPackage[k].Bidamount = qu.Float64All(data[0])
+						break
+					} else if in.Field == "bidstatus" {
+						if j.BlockPackage[k].BidStatus == "" {
+							j.BlockPackage[k].BidStatus = val
+							break
+						}
+					} else if in.Field == "projectname" {
+						if j.BlockPackage[k].Name == "" {
+							j.BlockPackage[k].Name = val
+							break
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
 //lua脚本根据属性设置提取kv值
 func getKvByLuaFields(vc *RuleCore, j *ju.Job, et *ExtractTask) (map[string][]map[string]interface{}, bool) {
 	kvmap := map[string][]map[string]interface{}{}
@@ -1179,6 +1331,22 @@ func ExtRegBack(j *ju.Job, in *RegLuaInfo, t *TaskInfo) {
 	}
 }
 
+//后置过滤
+func ExtRegBackPkg(j *ju.Job, in *RegLuaInfo) {
+	defer qu.Catch()
+	for k, v := range j.BlockPackage {
+		if in.Field == "winner" {
+			j.BlockPackage[k].Winner = in.RegPreBac.Reg.ReplaceAllString(v.Winner, in.RegPreBac.Replace)
+		} else if in.Field == "bidstatus" {
+			j.BlockPackage[k].BidStatus = in.RegPreBac.Reg.ReplaceAllString(v.BidStatus, in.RegPreBac.Replace)
+		} else if in.Field == "" {
+			j.BlockPackage[k].Text = in.RegPreBac.Reg.ReplaceAllString(v.Text, in.RegPreBac.Replace)
+		} else if in.Field == "projectname" {
+			j.BlockPackage[k].Name = in.RegPreBac.Reg.ReplaceAllString(v.Name, in.RegPreBac.Replace)
+		}
+	}
+}
+
 //KV过滤
 func ExtRuleKV(j *ju.Job, in *RegLuaInfo, t *TaskInfo) {
 	defer qu.Catch()

+ 108 - 56
src/jy/extract/extractInit.go

@@ -85,15 +85,20 @@ type ExtractTask struct {
 
 	ResultChanel chan bool //抽取结果详情
 	sync.RWMutex
-	ResultArr [][]map[string]interface{} //抽取结果详情
-	BidChanel chan bool                  //抽取结果
-	BidArr    [][]map[string]interface{} //抽取结果
-	BidTotal int                         //结果数量
+	ResultArr [][]map[string]interface {
+	}                   //抽取结果详情
+	BidChanel chan bool //抽取结果
+	BidArr    [][]map[string]interface {
+	}                   //抽取结果
+	BidTotal int        //结果数量
 
-	RecogFieldMap map[string]map[string]interface{}   //识别字段
-	FidClassMap   map[string][]map[string]interface{} //分类
-	CidRuleMap map[string][]map[string]interface{}    //规则
-	AuditFields []string                              //需要审核的字段名称
+	RecogFieldMap map[string]map[string]interface {
+	}                    //识别字段
+	FidClassMap map[string][]map[string]interface {
+	}                    //分类
+	CidRuleMap map[string][]map[string]interface {
+	}                    //规则
+	AuditFields []string //需要审核的字段名称
 
 	SiteCityMap          map[string]*SiteCity //站点对应的省市区
 	ProvinceMap          map[string]string    //省全称简称(key:浙江省 val:浙江)
@@ -119,7 +124,8 @@ type ExtractTask struct {
 	PostCodeMap map[string]*PostCode //邮编
 	AreaCodeMap map[string]*AreaCode //区号
 
-	InfoType []map[string]interface{}
+	InfoType []map[string]interface {
+	}
 
 	Trie_Full_Province  *ju.Trie       //省全称 省、直辖市、自治区
 	Trie_Full_City      *ju.Trie       //市全称 地级市
@@ -385,7 +391,7 @@ func (e *ExtractTask) InitRuleCore(isSite bool) {
 	defer qu.Catch()
 	allFields := getALLFields()
 	e.Fields = map[string]int{}
-	var versioninfodb, rule_logicdb, rule_logicpredb, rule_logicbackdb, rule_logicoredb,rule_logickvdb string
+	var versioninfodb, rule_logicdb, rule_logicpredb, rule_logicbackdb, rule_logicoredb, rule_logickvdb string
 	eSiteRuleCores := make(map[string]map[string][]*RuleCore)
 	if isSite {
 		versioninfodb = "site_versioninfo"
@@ -393,7 +399,7 @@ func (e *ExtractTask) InitRuleCore(isSite bool) {
 		rule_logicpredb = "site_rule_logicpre"
 		rule_logicbackdb = "site_rule_logicback"
 		rule_logicoredb = "site_rule_logicore"
-		rule_logickvdb= "site_rule_logickv"
+		rule_logickvdb = "site_rule_logickv"
 		e.SiteRuleCores = make(map[string]map[string][]*RuleCore)
 	} else {
 		versioninfodb = "versioninfo"
@@ -401,7 +407,7 @@ func (e *ExtractTask) InitRuleCore(isSite bool) {
 		rule_logicpredb = "rule_logicpre"
 		rule_logicbackdb = "rule_logicback"
 		rule_logicoredb = "rule_logicore"
-		rule_logickvdb= "rule_logickv"
+		rule_logickvdb = "rule_logickv"
 		e.RuleCores = make(map[string]map[string][]*RuleCore)
 	}
 
@@ -679,55 +685,101 @@ func (e *ExtractTask) InitPkgCore() {
 			continue
 		}
 		s_field := qu.ObjToString(pkginfo["s_field"])
-		pid := qu.BsonIdToSId(pkginfo["_id"])
-		logicList, _ := db.Mgo.Find("pkg_logic", `{"pid":"`+pid+`","delete":false}`, nil, nil, false, -1, -1)
-		for _, vv := range *logicList {
-			if b, _ := vv["isuse"].(bool); !b {
-				continue
+		sid := qu.BsonIdToSId(pkginfo["_id"])
+		rcore := &RuleCore{}
+		rcore.Field = s_field
+		rcore.ExtFrom = "detail"
+		//后置规则
+		ruleBacks := []*RegLuaInfo{}
+		blist, _ := db.Mgo.Find("pkg_logicback", `{"sid":"`+sid+`","delete":false}`, nil, nil, false, -1, -1)
+		for _, v := range *blist {
+			rinfo := &RegLuaInfo{
+				Field: qu.ObjToString(v["s_field"]),
+				Code:  v["s_code"].(string),
+				Name:  v["s_name"].(string),
+				IsLua: qu.If(v["s_type"].(string) == "1", true, false).(bool),
 			}
-			rcore := &RuleCore{}
-			rcore.Field = s_field
-			rcore.LuaLogic = qu.ObjToString(vv["s_luascript"]) //是否进入逻辑脚本
-			rcore.ExtFrom = qu.If(vv["extfrom"].(bool), "title", "detail").(string)
-			//后置规则
-			ruleBacks := []*RegLuaInfo{}
-			blist, _ := db.Mgo.Find("pkg_logicback", `{"sid":"`+qu.BsonIdToSId(vv["_id"])+`","delete":false}`, nil, nil, false, -1, -1)
-			for _, v := range *blist {
-				rinfo := &RegLuaInfo{
-					Field: qu.ObjToString(v["s_field"]),
-					Code:  v["s_code"].(string),
-					Name:  v["s_name"].(string),
-					IsLua: qu.If(v["s_type"].(string) == "1", true, false).(bool),
-				}
-				if rinfo.IsLua {
-					rinfo.RuleText = v["s_luascript"].(string)
+			if rinfo.IsLua {
+				rinfo.RuleText = v["s_luascript"].(string)
+				ruleBacks = append(ruleBacks, rinfo)
+			} else {
+				qu.Try(func() {
+					rinfo.RuleText = v["s_rule"].(string)
+					tmp := strings.Split(rinfo.RuleText, "__")
+					var pattern string
+					if strings.Contains(tmp[0], "\\u") {
+						tmp[0] = strings.Replace(tmp[0], "\\", "\\\\", -1)
+						tmp[0] = strings.Replace(tmp[0], "\\\\u", "\\u", -1)
+						pattern, _ = strconv.Unquote(`"` + tmp[0] + `"`)
+					} else {
+						pattern = tmp[0]
+					}
+					if len(tmp) == 2 {
+						rinfo.RegPreBac = &ExtReg{Reg: regexp.MustCompile(pattern), Replace: tmp[1]}
+					} else {
+						rinfo.RegPreBac = &ExtReg{Reg: regexp.MustCompile(pattern), Replace: ""}
+					}
 					ruleBacks = append(ruleBacks, rinfo)
-				} else {
-					qu.Try(func() {
-						rinfo.RuleText = v["s_rule"].(string)
-						tmp := strings.Split(rinfo.RuleText, "__")
-						var pattern string
-						if strings.Contains(tmp[0], "\\u") {
-							tmp[0] = strings.Replace(tmp[0], "\\", "\\\\", -1)
-							tmp[0] = strings.Replace(tmp[0], "\\\\u", "\\u", -1)
-							pattern, _ = strconv.Unquote(`"` + tmp[0] + `"`)
-						} else {
-							pattern = tmp[0]
-						}
-						if len(tmp) == 2 {
-							rinfo.RegPreBac = &ExtReg{Reg: regexp.MustCompile(pattern), Replace: tmp[1]}
-						} else {
-							rinfo.RegPreBac = &ExtReg{Reg: regexp.MustCompile(pattern), Replace: ""}
+				}, func(err interface{}) {
+					log.Debug(rinfo.Code, rinfo.Field, err)
+				})
+			}
+		}
+		rcore.RuleBacks = ruleBacks
+		//抽取规则
+		ruleCores := []*RegLuaInfo{}
+		clist, _ := db.Mgo.Find("pkg_logicore", `{"sid":"`+sid+`","delete":false}`, nil, nil, false, -1, -1)
+		for _, v := range *clist {
+			if b, _ := v["isuse"].(bool); !b {
+				continue
+			}
+			field := qu.ObjToString(v["s_field"])
+			e.Fields[field] = 1 //加入抽取属性组备用
+			rinfo := &RegLuaInfo{
+				Field: field,
+				Code:  v["s_code"].(string),
+				Name:  v["s_name"].(string),
+				IsLua: qu.If(v["s_type"].(string) == "1", true, false).(bool),
+			}
+			if rinfo.IsLua {
+				rinfo.RuleText = v["s_luascript"].(string)
+				//提取全部属性
+				ruleCores = append(ruleCores, rinfo)
+			} else {
+				qu.Try(func() {
+					rinfo.RuleText = v["s_rule"].(string)
+					tmp := strings.Split(rinfo.RuleText, "__")
+					var pattern string
+					if strings.Contains(tmp[0], "\\u") {
+						tmp[0] = strings.Replace(tmp[0], "\\", "\\\\", -1)
+						tmp[0] = strings.Replace(tmp[0], "\\\\u", "\\u", -1)
+						pattern, _ = strconv.Unquote(`"` + tmp[0] + `"`)
+					} else {
+						pattern = tmp[0]
+					}
+					if len(tmp) == 2 {
+						epos := strings.Split(tmp[1], ",")
+						posm := map[string]int{}
+						for _, v := range epos {
+							ks := strings.Split(v, ":")
+							if len(ks) == 2 { //(.*)招标公告(.*)__2:projectname,4:area
+								posm[ks[1]] = qu.IntAll(ks[0])
+							} else { //(.*)招标公告__2
+								posm[rinfo.Field] = qu.IntAll(ks[0])
+							}
 						}
-						ruleBacks = append(ruleBacks, rinfo)
-					}, func(err interface{}) {
-						log.Debug(rinfo.Code, rinfo.Field, err)
-					})
-				}
+						rinfo.RegCore = &ExtReg{Reg: regexp.MustCompile(pattern), Bextract: true, ExtractPos: posm}
+					} else {
+						rinfo.RegCore = &ExtReg{Reg: regexp.MustCompile(pattern), Bextract: false}
+					}
+					ruleCores = append(ruleCores, rinfo)
+				}, func(err interface{}) {
+					log.Debug(rinfo.Code, rinfo.Field, err)
+				})
 			}
-			rcore.RuleBacks = ruleBacks
-			e.PkgRuleCores = append(e.PkgRuleCores, rcore)
 		}
+		rcore.RuleCores = ruleCores
+		e.PkgRuleCores = append(e.PkgRuleCores, rcore)
 	}
 }
 

+ 1 - 0
src/jy/extract/extractudp.go

@@ -106,6 +106,7 @@ func ExtractByUdp(sid, eid string, ra *net.UDPAddr, instanceId ...string) {
 		ext.InitRuleCore(false)
 		ext.InitRuleCore(true)
 		ext.InitBlockRule()
+		ext.InitPkgCore()
 		ext.InitTag(false)
 		ext.InitTag(true)
 		ext.InitClearFn(false)

+ 99 - 22
src/jy/pretreated/analystep.go

@@ -11,7 +11,7 @@ import (
 	"github.com/PuerkitoBio/goquery"
 )
 
-func AnalyStart(job *util.Job,isSite bool,codeSite string) {
+func AnalyStart(job *util.Job, isSite bool, codeSite string) {
 	con := job.Content
 	//全文的需要修复表格
 	con = RepairCon(con)
@@ -28,23 +28,23 @@ func AnalyStart(job *util.Job,isSite bool,codeSite string) {
 			ration = newration
 		}
 	}
-	blockArrays, _ := DivideBlock(job.CategorySecond, con, 1, job.RuleBlock,isSite,codeSite) //分块
+	blockArrays, _ := DivideBlock(job.CategorySecond, con, 1, job.RuleBlock, isSite, codeSite) //分块
 	if len(blockArrays) > 0 { //有分块
 		//从块里面找分包
-		job.BlockPackage = FindPackageFromBlocks(&blockArrays,isSite,codeSite) //从块里面找分包
+		job.BlockPackage = FindPackageFromBlocks(&blockArrays, isSite, codeSite) //从块里面找分包
 		for _, bl := range blockArrays {
 			//log.Println(bl.Text)
 			if len([]rune(bl.Text)) > 80 {
-				bl.Block, _ = DivideBlock(job.CategorySecond, bl.Text, 1, job.RuleBlock,isSite,codeSite)
+				bl.Block, _ = DivideBlock(job.CategorySecond, bl.Text, 1, job.RuleBlock, isSite, codeSite)
 				for _, bl_bl := range bl.Block {
-					processTableInBlock(bl_bl, job, false,isSite,codeSite)
+					processTableInBlock(bl_bl, job, false, isSite, codeSite)
 				}
 			}
 			FindProjectCode(bl.Text, job) //匹配项目编号
-			processTableInBlock(bl, job, true,isSite,codeSite)
+			processTableInBlock(bl, job, true, isSite, codeSite)
 			//新加 未分块table中未能解析到中标候选人,从正文中解析
 			if job.Winnerorder == nil || len(job.Winnerorder) == 0 {
-				bl.Winnerorder = winnerOrderEntity.Find(bl.Text, true, 1,isSite,codeSite)
+				bl.Winnerorder = winnerOrderEntity.Find(bl.Text, true, 1, isSite, codeSite)
 				job.Winnerorder = bl.Winnerorder
 			}
 			job.Block = append(job.Block, bl)
@@ -56,48 +56,125 @@ func AnalyStart(job *util.Job,isSite bool,codeSite string) {
 		if len(tabs) > 0 { //解析表格逻辑
 			job.HasTable = 1 //添加标识:文本中有table
 			newCon = TextAfterRemoveTable(con)
-			job.BlockPackage = FindPackageFromText(job.Title, newCon,isSite,codeSite)
+			job.BlockPackage = FindPackageFromText(job.Title, newCon, isSite, codeSite)
 			for i := 0; i < len(tabs); i++ {
 				//log.Println(tabs[i].Text())
 				//添加标识:文本中有table
-				tabres := AnalyTableV2(tabs[i], job.Category, "", con, 1, job.SourceMid, job.RuleBlock,isSite,codeSite) //解析表格入口 返回:汇总表格对象
-				processTableResult(tabres, bl, job,isSite,codeSite)
+				tabres := AnalyTableV2(tabs[i], job.Category, "", con, 1, job.SourceMid, job.RuleBlock, isSite, codeSite) //解析表格入口 返回:汇总表格对象
+				processTableResult(tabres, bl, job, isSite, codeSite)
 			}
 		} else {
 			//从正文里面找分包
-			job.BlockPackage = FindPackageFromText(job.Title, newCon,isSite,codeSite)
+			job.BlockPackage = FindPackageFromText(job.Title, newCon, isSite, codeSite)
 		}
 		bl.Text = HtmlToText(con)
 		//log.Println(bl.Text)
 		FindProjectCode(bl.Text, job) //匹配项目编号
 		//调用kv解析
-		bl.ColonKV = GetKVAll(bl.Text, "", nil, 1,isSite,codeSite)
-		bl.SpaceKV = SspacekvEntity.Entrance(bl.Text, "", nil,isSite,codeSite)
+		bl.ColonKV = GetKVAll(bl.Text, "", nil, 1, isSite, codeSite)
+		bl.SpaceKV = SspacekvEntity.Entrance(bl.Text, "", nil, isSite, codeSite)
 		//新加 未分块table中未能解析到中标候选人,从正文中解析
 		if job.Winnerorder == nil || len(job.Winnerorder) == 0 {
-			bl.Winnerorder = winnerOrderEntity.Find(bl.Text, true, 1,isSite,codeSite)
+			bl.Winnerorder = winnerOrderEntity.Find(bl.Text, true, 1, isSite, codeSite)
 			job.Winnerorder = bl.Winnerorder
 		}
+		if len(job.BlockPackage) > 0 {
+			tmpn := 0
+			for k, _ := range job.BlockPackage {
+				if k == "" {
+					continue
+				}
+				tmpn++
+			}
+			if tmpn == 1 {
+				for k, jv := range job.BlockPackage {
+					if k == "" {
+						continue
+					}
+					if len(jv.WinnerOrder) == 0 && jv.Winner == "" {
+						winbs := make(map[string]bool, 0)
+						tmpw := 0
+						if bl.TableKV != nil {
+							for kk, v := range bl.TableKV.KvTags {
+								if strings.Contains(kk, "中标候选人") && WinnerOrderStr.MatchString(kk){
+									for _, vv := range v {
+										if winbs[vv.Value] {
+											continue
+										}
+										job.BlockPackage[k].WinnerOrder = append(job.BlockPackage[k].WinnerOrder, map[string]interface{}{
+											"type":    0,
+											"price":   0.0,
+											"entname": vv.Value,
+											"sort":    tmpw,
+										})
+										tmpw++
+										winbs[vv.Value] = true
+									}
+								}
+							}
+						}
+						if bl.SpaceKV != nil {
+							for kk, v := range bl.SpaceKV.KvTags {
+								if strings.Contains(kk, "中标候选人") && WinnerOrderStr.MatchString(kk){
+									for _, vv := range v {
+										if winbs[vv.Value] {
+											continue
+										}
+										job.BlockPackage[k].WinnerOrder = append(job.BlockPackage[k].WinnerOrder, map[string]interface{}{
+											"type":    0,
+											"price":   0.0,
+											"entname": vv.Value,
+											"sort":    tmpw,
+										})
+										tmpw++
+										winbs[vv.Value] = true
+									}
+								}
+							}
+						}
+						if bl.ColonKV != nil {
+							for kk, v := range bl.ColonKV.KvTags {
+								if strings.Contains(kk, "中标候选人") && WinnerOrderStr.MatchString(kk){
+									for _, vv := range v {
+										if winbs[vv.Value] {
+											continue
+										}
+										job.BlockPackage[k].WinnerOrder = append(job.BlockPackage[k].WinnerOrder, map[string]interface{}{
+											"type":    0,
+											"price":   0.0,
+											"entname": vv.Value,
+											"sort":    tmpw,
+										})
+										tmpw++
+										winbs[vv.Value] = true
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
 		job.Block = append(job.Block, bl)
 	}
 }
 
-func processTableInBlock(bl *util.Block, job *util.Job, packageFlag,isSite bool,codeSite string) {
+func processTableInBlock(bl *util.Block, job *util.Job, packageFlag, isSite bool, codeSite string) {
 	//块中再查找表格(块,处理完把值赋到块)
 	tabs, _ := ComputeConRatio(bl.Text, 2)
 	for _, tab := range tabs {
 		job.HasTable = 1
 		tmptag := ""
-		if tab.Nodes[0] != nil && tab.Nodes[0].PrevSibling != nil{
+		if tab.Nodes[0] != nil && tab.Nodes[0].PrevSibling != nil {
 			tmptag = strings.TrimSpace(tab.Nodes[0].PrevSibling.Data)
 		}
 		//添加标识:文本中有table
-		tabres := AnalyTableV2(tab, job.Category, tmptag, tab.Text(), 2, job.SourceMid, job.RuleBlock,isSite,codeSite) //解析表格入口 返回:汇总表格对象
+		tabres := AnalyTableV2(tab, job.Category, tmptag, tab.Text(), 2, job.SourceMid, job.RuleBlock, isSite, codeSite) //解析表格入口 返回:汇总表格对象
 		if packageFlag {
 			tabres.PackageMap = nil
 			tabres.IsMultiPackage = false
 		}
-		processTableResult(tabres, bl, job,isSite,codeSite) //分析table解析结果
+		processTableResult(tabres, bl, job, isSite, codeSite) //分析table解析结果
 		if bl.Title == "" && tabres.BlockTag != "" {
 			bl.Title = tabres.BlockTag
 		}
@@ -170,7 +247,7 @@ func FindProjectCode(newCon string, job *util.Job) {
 }
 
 //分析table解析结果
-func processTableResult(tabres *TableResult, block *util.Block, job *util.Job,isSite bool,codeSite string) {
+func processTableResult(tabres *TableResult, block *util.Block, job *util.Job, isSite bool, codeSite string) {
 	//解析结果中的kv
 	if block.TableKV == nil {
 		block.TableKV = util.NewJobKv()
@@ -202,19 +279,19 @@ func processTableResult(tabres *TableResult, block *util.Block, job *util.Job,is
 			} else {
 				blockPackage.TableKV = util.NewJobKv()
 			}
-			MergeKvTags(blockPackage.TableKV.KvTags, GetKvTags(labelKVs, "", nil,isSite,codeSite))
+			MergeKvTags(blockPackage.TableKV.KvTags, GetKvTags(labelKVs, "", nil, isSite, codeSite))
 			tablePackage[v] = blockPackage
 		}
 	}
 	//处理中标人排序
 	wror := []map[string]interface{}{}
-	for _, v := range tabres.WinnerOrder {
+	for i, v := range tabres.WinnerOrder {
 		entName, _ := v["entname"].(string)
 		v["entname"] = winnerOrderEntity.clear("中标单位", entName)
 		if price, ok := v["price"].(string); ok {
 			v["price"] = winnerOrderEntity.clear("中标金额", price)
 		}
-		v["type"] = 2
+		v["type"] = i
 		wror = append(wror, v)
 	}
 	if len(wror) > 0 {

+ 102 - 77
src/jy/pretreated/analytable.go

@@ -110,6 +110,7 @@ var (
 	jsonReg                     = regexp.MustCompile(`\{.+:[^}]*\} `) //  \{".*\":\".+\"}
 	regHz                       = regexp.MustCompile("[\u4e00-\u9fa5]")
 	winnerOrderAndBidResult     = regexp.MustCompile("((中标)?候选人|(中标|评标)结果)")
+	WinnerOrderStr = regexp.MustCompile(`(集团|公司|学校|中心|家具城|门诊|\[大中小\]学|部|院|局|厂|店|所|队|社|室|厅|段|会|场|行)$`)
 )
 
 //在解析时,判断表格元素是否隐藏
@@ -123,7 +124,7 @@ func IsHide(g *goquery.Selection) (b bool) {
 
 //对表格的key进行标准化处理,多个k相同时,出现覆盖问题
 //待扩展,暂不支持正则标签库
-func CommonDataAnaly(k, tabletag, tabledesc string, v interface{},isSite bool,codeSite string) (kvTags map[string][]*u.Tag, returntag string) {
+func CommonDataAnaly(k, tabletag, tabledesc string, v interface{}, isSite bool, codeSite string) (kvTags map[string][]*u.Tag, returntag string) {
 	kvTags = map[string][]*u.Tag{}
 	v1 := ""
 	if sv, sok := v.(string); sok { //取KV
@@ -142,9 +143,9 @@ func CommonDataAnaly(k, tabletag, tabledesc string, v interface{},isSite bool,co
 	k1 := ClearKey(k, 2)
 	//u.Debug(2, k)
 	//取标准key
-	res := u.GetTags(k1,isSite,codeSite)
+	res := u.GetTags(k1, isSite, codeSite)
 	if len(res) == 0 && k1 != k {
-		res = u.GetTags(k,isSite,codeSite)
+		res = u.GetTags(k, isSite, codeSite)
 		k1 = k
 	}
 	//log.Println(k, res)
@@ -170,7 +171,7 @@ func CommonDataAnaly(k, tabletag, tabledesc string, v interface{},isSite bool,co
 	} else {
 		kvTags[k] = append(kvTags[k], &u.Tag{Key: k, Value: v1, IsInvalid: true})
 		//没有取到标准化key时,对中标金额和中标单位的逻辑处理
-		if filter_zbje_k.MatchString(k) && !filter_zbje_kn.MatchString(k) && filter_zbje_v.MatchString(v1)&& utf8.RuneCountInString(v1) <20 {
+		if filter_zbje_k.MatchString(k) && !filter_zbje_kn.MatchString(k) && filter_zbje_v.MatchString(v1) && utf8.RuneCountInString(v1) < 20 {
 			if tabletag == "" {
 				returntag = "中标情况"
 			}
@@ -203,7 +204,7 @@ func CommonDataAnaly(k, tabletag, tabledesc string, v interface{},isSite bool,co
 }
 
 //对解析后的表格的kv进行过滤
-func (table *Table) KVFilter(isSite bool,codeSite string) {
+func (table *Table) KVFilter(isSite bool, codeSite string) {
 	//1.标准化值查找
 	//2.对数组的处理
 	//3.对分包的处理
@@ -228,10 +229,10 @@ func (table *Table) KVFilter(isSite bool,codeSite string) {
 			if k == "2、建设规模" {
 				k = "预算"
 			}
-			if k == `中标价(万元)\费率(%)`{
+			if k == `中标价(万元)\费率(%)` {
 				k = "中标价(万元)"
 			}
-			kvTags, tag := CommonDataAnaly(k, table.Tag, table.Desc, v,isSite,codeSite) //对key标准化处理,没有找到会走中标
+			kvTags, tag := CommonDataAnaly(k, table.Tag, table.Desc, v, isSite, codeSite) //对key标准化处理,没有找到会走中标
 			//qutil.Debug(k, v, k1, w1, v1, tag, b)
 			if tag != "" && table.Tag == "" {
 				table.Tag = tag
@@ -243,7 +244,7 @@ func (table *Table) KVFilter(isSite bool,codeSite string) {
 		}
 	}
 	//处理值是数组的kv放入标准化kv中//处理table.SortKV.value为数组的情况
-	table.sortKVArr(as,isSite,codeSite)
+	table.sortKVArr(as, isSite, codeSite)
 	//
 	if len(table.WinnerOrder) > 0 || !table.BPackage {
 		winnerOrder := []map[string]interface{}{}
@@ -275,7 +276,7 @@ func (table *Table) KVFilter(isSite bool,codeSite string) {
 	L: //遍历每个td,查询中标人
 		for _, tr := range table.TRs {
 			for _, td := range tr.TDs {
-				winnerOrder = winnerOrderEntity.Find(td.Val, true, 3,isSite,codeSite)
+				winnerOrder = winnerOrderEntity.Find(td.Val, true, 3, isSite, codeSite)
 				if len(winnerOrder) > 0 {
 					break L
 				}
@@ -306,7 +307,7 @@ func (table *Table) KVFilter(isSite bool,codeSite string) {
 }
 
 //处理table.SortKV.value为数组的情况
-func (table *Table) sortKVArr(as *SortMap,isSite bool,codeSite string) {
+func (table *Table) sortKVArr(as *SortMap, isSite bool, codeSite string) {
 	winnertag := iswinnertabletag.MatchString(table.Tag) && !nswinnertabletag.MatchString(table.Tag) //table标签
 	if !winnertag {
 		winnertag = iswinnertabletag.MatchString(table.TableResult.BlockTag) && !nswinnertabletag.MatchString(table.TableResult.BlockTag) //块标签
@@ -341,7 +342,7 @@ func (table *Table) sortKVArr(as *SortMap,isSite bool,codeSite string) {
 							res, _, _, _, repl := CheckCommon(k, "bidorder")
 							kv := ""
 							if !res {
-								kt := u.GetTags(filterThText.ReplaceAllString(ClearKey(k, 2), ""),isSite,codeSite)
+								kt := u.GetTags(filterThText.ReplaceAllString(ClearKey(k, 2), ""), isSite, codeSite)
 								if kt.Len() > 0 {
 									kv = kt[0].Value
 								}
@@ -445,12 +446,24 @@ func (table *Table) sortKVArr(as *SortMap,isSite bool,codeSite string) {
 					}
 				}
 			}
-			kvTags, tag := CommonDataAnaly(k, table.Tag, table.Desc, v,isSite,codeSite)
+			kvTags, tag := CommonDataAnaly(k, table.Tag, table.Desc, v, isSite, codeSite)
 			if tag != "" && table.Tag == "" {
 				table.Tag = tag
 			}
 			for kk, vv := range kvTags {
-				table.StandKV[kk] = append(table.StandKV[kk], vv...)
+				if vsss, ok := v.([]string); ok {
+					if len(vv) > 0{
+						for _,vvvvvv := range vsss{
+							tmp := u.Tag{}
+							tmp.Weight = vv[0].Weight
+							tmp.Key = vv[0].Key
+							tmp.IsInvalid = vv[0].IsInvalid
+							tmp.Value = vvvvvv
+							table.StandKV[kk] = append(table.StandKV[kk], &tmp)
+						}
+					}
+				}
+				//table.StandKV[kk] = append(table.StandKV[kk], vv...)
 				//				else if k2 == "中标金额" {
 				//					if qutil.Float64All(v1) > qutil.Float64All(table.StandKV[k2]) {
 				//						table.StandKV[k2] = v1
@@ -613,7 +626,7 @@ func (table *Table) MergerToTableresult() {
 解析表格入口
 返回:汇总表格对象
 **/
-func AnalyTableV2(tabs *goquery.Selection, toptype, blockTag, con string, itype int, _id interface{}, ruleBlock *u.RuleBlock,isSite bool,codeSite string) (tabres *TableResult) {
+func AnalyTableV2(tabs *goquery.Selection, toptype, blockTag, con string, itype int, _id interface{}, ruleBlock *u.RuleBlock, isSite bool, codeSite string) (tabres *TableResult) {
 	defer qutil.Catch()
 	//u.Debug(con)
 	if itype == 1 {
@@ -631,12 +644,12 @@ func AnalyTableV2(tabs *goquery.Selection, toptype, blockTag, con string, itype
 	tabres.GoqueryTabs = tabs
 	//}
 	//解析表格集
-	tabres.Analy(isSite,codeSite)
+	tabres.Analy(isSite, codeSite)
 	return
 }
 
 //开始解析表格集
-func (ts *TableResult) Analy(isSite bool,codeSite string) {
+func (ts *TableResult) Analy(isSite bool, codeSite string) {
 	tabs := []*Table{}
 	contactFormat := &u.ContactFormat{
 		IndexMap: map[int]string{},
@@ -645,7 +658,7 @@ func (ts *TableResult) Analy(isSite bool,codeSite string) {
 	//for _, table := range ts.GoqueryTabs {
 	tn := NewTable(ts.Html, ts, ts.GoqueryTabs)
 	//核心模块
-	tsw := tn.Analy(contactFormat,isSite,codeSite)
+	tsw := tn.Analy(contactFormat, isSite, codeSite)
 	for _, tab := range tsw {
 		if len(tab.TRs) > 0 {
 			tabs = append(tabs, tab)
@@ -684,7 +697,7 @@ func (ts *TableResult) Analy(isSite bool,codeSite string) {
 					if table.BlockPackage.Map[v1] == nil {
 						table.BPackage = true
 						table.BlockPackage.AddKey(v1, bp)
-					}else {
+					} else {
 						table.BlockPackage.RemoveKey(v1)
 						table.BlockPackage.AddKey(v1, bp)
 					}
@@ -743,23 +756,26 @@ func (ts *TableResult) Analy(isSite bool,codeSite string) {
 }
 
 //解析表格
-func (table *Table) Analy(contactFormat *u.ContactFormat,isSite bool,codeSite string) []*Table {
+func (table *Table) Analy(contactFormat *u.ContactFormat, isSite bool, codeSite string) []*Table {
 	//查找表体中的tr对象
 	trs := table.Goquery.ChildrenFiltered("tbody,thead,tfoot").ChildrenFiltered("tr")
 	if trs.Size() == 0 {
 		trs = table.Goquery.ChildrenFiltered("tr")
 	}
 	//遍历节点,初始化table 结构
-	table.createTabe(trs,isSite,codeSite)
+	table.createTabe(trs, isSite, codeSite)
+	if len(table.TRs) == 0 {
+		return []*Table{}
+	}
 	//重置行列
 	table.ComputeRowColSpan()
 	//对table结构体进行整体解析处理
-	ts := table.AnalyTables(contactFormat,isSite,codeSite)
+	ts := table.AnalyTables(contactFormat, isSite, codeSite)
 	return ts
 }
 
 //遍历节点,初始化table 结构体
-func (table *Table) createTabe(trs *goquery.Selection,isSite bool,codeSite string) {
+func (table *Table) createTabe(trs *goquery.Selection, isSite bool, codeSite string) {
 	trs.Each(func(n int, sel *goquery.Selection) {
 		//隐藏行不处理
 		if IsHide(sel) {
@@ -776,7 +792,7 @@ func (table *Table) createTabe(trs *goquery.Selection,isSite bool,codeSite strin
 				return
 			}
 			//进入每一个单元格
-			td := NewTD(selm, TR, table,isSite,codeSite) //初始化td,kv处理,td中有table处理,td的方向
+			td := NewTD(selm, TR, table, isSite, codeSite) //初始化td,kv处理,td中有table处理,td的方向
 			//num++
 			TR.AddTD(td)
 			if td.Val == "" && td.SonTableResult == nil && len(td.SortKV.Map) == 0 { //删除一个tr,tr中所有td是空值的
@@ -794,7 +810,7 @@ func (table *Table) createTabe(trs *goquery.Selection,isSite bool,codeSite strin
 }
 
 //对table进行整体解析处理
-func (tn *Table) AnalyTables(contactFormat *u.ContactFormat,isSite bool,codeSite string) []*Table {
+func (tn *Table) AnalyTables(contactFormat *u.ContactFormat, isSite bool, codeSite string) []*Table {
 	ts := tn.tableSubDemolitionTable() //分包,拆表
 	for n, table := range ts {
 		//处理每个table
@@ -803,15 +819,15 @@ func (tn *Table) AnalyTables(contactFormat *u.ContactFormat,isSite bool,codeSite
 			table.deleteTrimTr()
 			//table.Print()
 			//校对表格
-			table.Adjust(isSite,codeSite)
+			table.Adjust(isSite, codeSite)
 			//查找表格的标签,table.Tag字段
 			table.FindTag()
 			//log.Println(table.TableResult.Id, table.Html)
 			//分割表格
-			table.bSplit(n, ts,isSite,codeSite)
-			table.TdContactFormat(contactFormat,isSite,codeSite) //contactFormat,处理采购单位,代理机构
+			table.bSplit(n, ts, isSite, codeSite)
+			table.TdContactFormat(contactFormat, isSite, codeSite) //contactFormat,处理采购单位,代理机构
 			//开始查找kv,核心模块,table.SortKV
-			table.FindKV(isSite,codeSite)
+			table.FindKV(isSite, codeSite)
 			//table中抽取品牌,table.BrandData
 			if u.IsBrandGoods {
 				table.analyBrand()
@@ -819,7 +835,7 @@ func (tn *Table) AnalyTables(contactFormat *u.ContactFormat,isSite bool,codeSite
 			res, _, _, _, _ := CheckCommon(table.Tag, "abandontable")
 			if !res {
 				//过滤、标准化、合并kv,table.StandKV,table.StandKVWeight
-				table.KVFilter(isSite,codeSite)
+				table.KVFilter(isSite, codeSite)
 			}
 			//对没有表头表格的处理
 			if table.Tag != "" {
@@ -827,20 +843,20 @@ func (tn *Table) AnalyTables(contactFormat *u.ContactFormat,isSite bool,codeSite
 				if b {
 					table.BPackage = b
 					if len(table.BlockPackage.Map) == 0 {
-						for _,av := range m{
+						for _, av := range m {
 							kv := u.NewJobKv()
-							kv.KvTags= table.StandKV
-							bd:=u.PackageNumberConvert(av[0])
+							kv.KvTags = table.StandKV
+							bd := u.PackageNumberConvert(av[0])
 							blockPackage := &u.BlockPackage{
-								Origin:av[0],
-								Name:av[0],
-								Text:co,
-								TableKV:kv,
-								Index:bd,
+								Origin:  av[0],
+								Name:    av[0],
+								Text:    co,
+								TableKV: kv,
+								Index:   bd,
 							}
-							if bd !=""{
+							if bd != "" {
 								table.BlockPackage.AddKey(bd, blockPackage)
-							}else {
+							} else {
 								table.BlockPackage.AddKey(av[0], blockPackage)
 							}
 						}
@@ -849,7 +865,7 @@ func (tn *Table) AnalyTables(contactFormat *u.ContactFormat,isSite bool,codeSite
 				}
 			}
 			//判断是否是多包,并处理分包的//遍历td分块
-			table.CheckMultiPackageByTable(isSite,codeSite)
+			table.CheckMultiPackageByTable(isSite, codeSite)
 			//MergeKvTags(table.TableResult.KvTags, table.StandKV)
 		}
 	}
@@ -914,7 +930,7 @@ func (table *Table) tableSubDemolitionTable() []*Table {
 }
 
 //分割表格
-func (table *Table) bSplit(n int, ts []*Table,isSite bool,codeSite string) {
+func (table *Table) bSplit(n int, ts []*Table, isSite bool, codeSite string) {
 	if table.BSplit {
 		if !table.BHeader && n > 0 {
 			for i := n - 1; i > -1; i-- {
@@ -922,7 +938,7 @@ func (table *Table) bSplit(n int, ts []*Table,isSite bool,codeSite string) {
 					if ts[i].BFirstRow {
 						//取第一行插入到
 						table.InsertTR(ts[i].TRs[0])
-						table.Adjust(isSite,codeSite)
+						table.Adjust(isSite, codeSite)
 					}
 					break
 				}
@@ -953,7 +969,7 @@ func (table *Table) deleteTrimTr() {
 }
 
 //校对表格
-func (table *Table) Adjust(isSite bool,codeSite string) {
+func (table *Table) Adjust(isSite bool, codeSite string) {
 	//计算行列起止位置,跨行跨列处理
 	table.ComputeRowColSpan()
 	//	for k1, tr := range table.TRs {
@@ -988,7 +1004,7 @@ func (table *Table) Adjust(isSite bool,codeSite string) {
 	}
 	if float32(count)/float32(table.TDNum) < 0.85 {
 		//精确计算起止行列是表头的概率
-		table.ComputeRowColIsKeyRation(isSite,codeSite)
+		table.ComputeRowColIsKeyRation(isSite, codeSite)
 		bhead := false
 	L:
 		for i, tr := range table.TRs {
@@ -1000,7 +1016,7 @@ func (table *Table) Adjust(isSite bool,codeSite string) {
 						if res {
 							//删除此行
 							table.TRs = table.TRs[:len(table.TRs)-1]
-							table.Adjust(isSite,codeSite)
+							table.Adjust(isSite, codeSite)
 							return
 						}
 					}
@@ -1119,7 +1135,7 @@ func (table *Table) GetKeyRation() {
 }
 
 //计算行列是表头的概率调用GetKeyRation
-func (table *Table) ComputeRowColIsKeyRation(isSite bool,codeSite string) {
+func (table *Table) ComputeRowColIsKeyRation(isSite bool, codeSite string) {
 	//增加对跨行校正限止
 	//	u.Debug(table.Brule, table.ColNum, table.RowNum, table.TDNum)
 	bkeyfirstrow := false
@@ -1358,7 +1374,7 @@ func (table *Table) ComputeRowColIsKeyRation(isSite bool,codeSite string) {
 				tr.TDs[0].BH = false
 				tr.TDs[0].KVDirect = 0
 				sv := FindKv(tr.TDs[0].Val, "", 2)
-				_, resm := colonkvEntity.entrance(tr.TDs[0].Val, "", nil, 2,isSite,codeSite)
+				_, resm := colonkvEntity.entrance(tr.TDs[0].Val, "", nil, 2, isSite, codeSite)
 				for k, v := range resm {
 					sv.AddKey(k, v)
 				}
@@ -1393,7 +1409,7 @@ func (table *Table) ComputeRowColIsKeyRation(isSite bool,codeSite string) {
 }
 
 //查找表格的kv,调用FindTdVal
-func (table *Table) FindKV(isSite bool,codeSite string) {
+func (table *Table) FindKV(isSite bool, codeSite string) {
 	//判断全是key的表格不再查找
 	if table.BHeader { //只要一个是key即为true
 		direct := If(table.BFirstRow, 2, 1).(int) //kv,2查找方向,向上查找
@@ -1469,7 +1485,7 @@ func (table *Table) FindKV(isSite bool,codeSite string) {
 			for n, r := range r1 {
 				if len([]rune(r)) < 60 { // 长度小于60才去分
 					//res1, _ := GetKVAll(r, "", nil)
-					res1, _ := colonkvEntity.entrance(r, "", nil, 2,isSite,codeSite)
+					res1, _ := colonkvEntity.entrance(r, "", nil, 2, isSite, codeSite)
 					if res1 != nil {
 						nmap[n] = res1
 						nmapkeys = append(nmapkeys, n)
@@ -1691,7 +1707,7 @@ func GetBidSort(str string, n int) int {
 
 //查找每一个单元格的表头,调用FindNear
 func (table *Table) FindTdVal(td *TD, direct, vdirect int) (b bool) {
-	if td.Val == "" || strings.TrimSpace(td.Val) == ""{
+	if td.Val == "" || strings.TrimSpace(td.Val) == "" {
 		return
 	}
 	near := table.FindNear(td, direct)
@@ -1904,7 +1920,7 @@ func (tn *Table) GetTdByRCNo(row, col int) *TD {
 }
 
 //判断表格是否是分包
-func (tn *Table) CheckMultiPackageByTable(isSite bool,codeSite string) (b bool, index []string) {
+func (tn *Table) CheckMultiPackageByTable(isSite bool, codeSite string) (b bool, index []string) {
 	pac := 0             //包的数量
 	val := 0             //分值
 	index = []string{}   //存储分包,使用tbale.SortKV的key和value使用正则等处理对值进行判断
@@ -1968,28 +1984,35 @@ func (tn *Table) CheckMultiPackageByTable(isSite bool,codeSite string) (b bool,
 			for nk, v := range index {
 				if tn.BlockPackage.Map[v] == nil {
 					kv := u.NewJobKv()
-					kv.KvTags = tn.StandKV
+					for tnk,tnv := range tn.StandKV{
+						if nk >= len(tnv){
+							continue
+						}
+						kv.KvTags[tnk] = append(kv.KvTags[tnk], tnv[nk])
+					}
+					//kv.KvTags = tn.StandKV
 					bp := &u.BlockPackage{}
 					bp.Index = v                  //序号 (转换后编号,只有数字或字母)
 					bp.Origin = oldIndex[nk]      //包的原始值
 					bp.TableKV = kv               //table kv (分出的对应的KV值)
+					bp.Text = tn.Html
 					tn.BlockPackage.AddKey(v, bp) //table子包数组
 				}
 			}
-			isGoonNext = tn.manyPackageProcessByIndex(index, standIndex_pos,isSite,codeSite) //多包处理,处理不同情况下的分包
+			isGoonNext = tn.manyPackageProcessByIndex(index, standIndex_pos, isSite, codeSite) //多包处理,处理不同情况下的分包
 		}
 	} else {
 		isGoonNext = true
 	}
 	if isGoonNext { //没有处理成数组的情况下,继续调用正文查找分包的方法
-		tn.isGoonNext(isSite,codeSite)
+		tn.isGoonNext(isSite, codeSite)
 	}
 	//查找分包中的中标人排序
 	if tn.BlockPackage != nil && tn.BlockPackage.Keys != nil && len(tn.BlockPackage.Keys) > 0 {
 		for _, v := range tn.BlockPackage.Keys {
 			vv, ok := tn.BlockPackage.Map[v].(*u.BlockPackage)
 			if ok && (vv.WinnerOrder == nil || len(vv.WinnerOrder) == 0) {
-				vv.WinnerOrder = winnerOrderEntity.Find(vv.Text, true, 2,isSite,codeSite)
+				vv.WinnerOrder = winnerOrderEntity.Find(vv.Text, true, 2, isSite, codeSite)
 			}
 		}
 	}
@@ -1997,7 +2020,7 @@ func (tn *Table) CheckMultiPackageByTable(isSite bool,codeSite string) (b bool,
 }
 
 //多包处理,处理不同情况下的分包
-func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int,isSite bool,codeSite string) (isGoonNext bool) {
+func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int, isSite bool, codeSite string) (isGoonNext bool) {
 	if len(index) == 1 { //是一个的情况
 		if len(tn.SortKV.Keys) < 10 && tn.ColNum < 10 && tn.RowNum < 4 { //table带排序的KV值小于10并且小于10列和小于4行
 			beq := true
@@ -2038,7 +2061,7 @@ func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int,
 		if val, bvs := v1.([]string); bvs {
 			if len(val) <= len(index) { //table.SortKV.Map.value数组小于等于分包index
 				for k, v := range val {
-					tn.assemblePackage(k1, v, index[k],isSite,codeSite) //组装解析到的分包
+					tn.assemblePackage(k1, v, index[k], isSite, codeSite) //组装解析到的分包
 				}
 			} else {
 				for sk1, sv2 := range index {
@@ -2056,12 +2079,12 @@ func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int,
 							}
 						}
 					}
-					tn.assemblePackage(k1, v, sv2,isSite,codeSite)
+					tn.assemblePackage(k1, v, sv2, isSite, codeSite)
 				}
 			}
 			//删除子包的kv
 			//u.Debug("----==1==-------", k1)
-			k1tags := u.GetTags(k1,isSite,codeSite) //取得匹配
+			k1tags := u.GetTags(k1, isSite, codeSite) //取得匹配
 			//if !(len(k1tags) > 0 && k1tags[0].Value == "采购单位") {
 			//	tn.SortKV.RemoveKey(k1)
 			//}
@@ -2071,7 +2094,7 @@ func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int,
 			}
 		} else if val, bvs := v1.(string); bvs && len(index) == 1 {
 			//删除子包的kv
-			kvTags, _ := CommonDataAnaly(k1, "", "", val,isSite,codeSite)
+			kvTags, _ := CommonDataAnaly(k1, "", "", val, isSite, codeSite)
 			for kvTag_k, kvTag_v := range kvTags {
 				hasValid := false
 				for _, kvTag_vv := range kvTag_v {
@@ -2085,7 +2108,7 @@ func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int,
 				}
 				if !(len(kvTags) > 0 && regexp.MustCompile("^(项目|开标|采购单位|招标机构)").MatchString(kvTag_k)) {
 					tn.SortKV.RemoveKey(k1)
-					tn.assemblePackage(k1, val, index[0],isSite,codeSite)
+					tn.assemblePackage(k1, val, index[0], isSite, codeSite)
 					//log.Println("remove", k1, val)
 				}
 			}
@@ -2097,7 +2120,7 @@ func (tn *Table) manyPackageProcessByIndex(index []string, standIndex_pos []int,
 }
 
 //没有处理成数组的情况下,继续调用正文查找分包的方法
-func (tn *Table) isGoonNext(isSite bool,codeSite string) {
+func (tn *Table) isGoonNext(isSite bool, codeSite string) {
 	blockPackage := map[string]*u.BlockPackage{}
 	for _, k := range tn.SortKV.Keys {
 		if excludeKey.MatchString(k) || strings.Contains(k, "批复") {
@@ -2111,7 +2134,7 @@ func (tn *Table) isGoonNext(isSite bool,codeSite string) {
 		} else {
 			str += fmt.Sprintf("%s:%s\n", nk, v)
 		}
-		b, _ := divisionPackageChild(&blockPackage, str, tn.Tag, false, false,isSite,codeSite) //分块之后分包
+		b, _ := divisionPackageChild(&blockPackage, str, tn.Tag, false, false, isSite, codeSite) //分块之后分包
 		if b && len(blockPackage) > 0 {
 			tn.BPackage = true
 			for mk, mv := range blockPackage {
@@ -2318,15 +2341,17 @@ func initCheckMultiPackageByTable(tn *Table, key_index int, index []string, inde
 }
 
 //组装解析到的分包,//key如果匹配到抽取关键词就添加到table.SortKV
-func (tn *Table) assemblePackage(k1, v1, key string,isSite bool,codeSite string) {
+func (tn *Table) assemblePackage(k1, v1, key string, isSite bool, codeSite string) {
 	bp := tn.BlockPackage.Map[key].(*u.BlockPackage)
 	if bp.TableKV == nil {
 		bp.TableKV = u.NewJobKv()
 	}
 	if v1 != "" {
-		kvTags, _ := CommonDataAnaly(k1, "中标情况", "", v1,isSite,codeSite) //匹配抽取关键词
+		kvTags, _ := CommonDataAnaly(k1, "中标情况", "", v1, isSite, codeSite) //匹配抽取关键词
 		for k3, v3 := range kvTags {
-			bp.TableKV.KvTags[k3] = append(bp.TableKV.KvTags[k3], v3...)
+			if bp.TableKV.KvTags[k3] == nil {
+				bp.TableKV.KvTags[k3] = append(bp.TableKV.KvTags[k3], v3...)
+			}
 		}
 	}
 	k1 = regReplAllSpace.ReplaceAllString(k1, "")
@@ -2481,7 +2506,7 @@ func replPkgConfusion(v1 string) string {
 }
 
 //对td中的值,进行再处理
-func (tn *Table) TdContactFormat(contactFormat *u.ContactFormat,isSite bool,codeSite string) {
+func (tn *Table) TdContactFormat(contactFormat *u.ContactFormat, isSite bool, codeSite string) {
 	//处理表格中的联系人信息
 	indexMap := contactFormat.IndexMap
 	matchMap := contactFormat.MatchMap
@@ -2553,7 +2578,7 @@ L:
 			//和|以?及|与|、多个词和在一起
 			jumpNextTd, thisTrHasMatch = tn.tdsMultipleWords(jumpNextTd, td, td_index, tr, thisTrHasMatch, indexMap)
 			//分块之后的kv
-			thisTdKvs := kvAfterDivideBlock("", td.Text, 3, tn.TableResult.RuleBlock,isSite,codeSite)
+			thisTdKvs := kvAfterDivideBlock("", td.Text, 3, tn.TableResult.RuleBlock, isSite, codeSite)
 			if len(thisTdKvs) == 0 {
 				thisTdKvs = tn.tdkv(td) //获取冒号kv
 			}
@@ -2581,7 +2606,7 @@ L:
 				//都为正序查询
 				if allAscFind && tdAscFind {
 					//都为正序查询处理
-					matchCount, weightMap, matchMap, thisTrHasMatch, indexMap, iscontinue, reCreate, thidTdIndex = tn.asdFind(td_k, matchCount, weightMap, matchMap, td, thisTrHasMatch, td_kv, indexMap, iscontinue, reCreate, thidTdIndex,isSite,codeSite)
+					matchCount, weightMap, matchMap, thisTrHasMatch, indexMap, iscontinue, reCreate, thidTdIndex = tn.asdFind(td_k, matchCount, weightMap, matchMap, td, thisTrHasMatch, td_kv, indexMap, iscontinue, reCreate, thidTdIndex, isSite, codeSite)
 				}
 				if iscontinue {
 					continue
@@ -2651,7 +2676,7 @@ L:
 					}
 					thisTrHasMatch = true
 					//modle
-					modle(thisTdKvs, td, myContactType, td_k, td_v, &contactTypeTagMap, tn, &weightMap, tr_index, td_index,isSite,codeSite)
+					modle(thisTdKvs, td, myContactType, td_k, td_v, &contactTypeTagMap, tn, &weightMap, tr_index, td_index, isSite, codeSite)
 				}
 			}
 			//u.Debug(td.SortKV.Map)
@@ -2679,7 +2704,7 @@ L:
 }
 
 //modle
-func modle(thisTdKvs []*u.Kv, td *TD, myContactType, td_k, td_v string, contactTypeTagMap *map[string]map[string][]interface{}, tn *Table, weightMap *map[string]map[string]interface{}, tr_index, td_index int,isSite bool,codeSite string) {
+func modle(thisTdKvs []*u.Kv, td *TD, myContactType, td_k, td_v string, contactTypeTagMap *map[string]map[string][]interface{}, tn *Table, weightMap *map[string]map[string]interface{}, tr_index, td_index int, isSite bool, codeSite string) {
 	modle := 0
 	if len(thisTdKvs) == 1 {
 		if regReplAllSpace.ReplaceAllString(thisTdKvs[0].Value, "") == "" {
@@ -2694,7 +2719,7 @@ func modle(thisTdKvs []*u.Kv, td *TD, myContactType, td_k, td_v string, contactT
 	} else {
 		//
 		if !strings.HasSuffix(td_k, "方式") {
-			kvTags := GetKvTags([]*u.Kv{&u.Kv{Key: myContactType + td_k, Value: td_v}}, "", BuyerContacts,isSite,codeSite)
+			kvTags := GetKvTags([]*u.Kv{&u.Kv{Key: myContactType + td_k, Value: td_v}}, "", BuyerContacts, isSite, codeSite)
 			if len(kvTags) == 1 {
 				tagVal, _ := u.FirstKeyValueInMap(kvTags)
 				if tagVal == "采购单位联系人" && ContactBuyerPersonFilterReg.MatchString(td_v) {
@@ -2721,7 +2746,7 @@ func modle(thisTdKvs []*u.Kv, td *TD, myContactType, td_k, td_v string, contactT
 }
 
 //都为正序查询
-func (tn *Table) asdFind(td_k string, matchCount int, weightMap map[string]map[string]interface{}, matchMap map[string]map[string]bool, td *TD, thisTrHasMatch bool, td_kv *u.Kv, indexMap map[int]string, iscontinue bool, reCreate bool, thidTdIndex int,isSite bool,codeSite string) (int, map[string]map[string]interface{}, map[string]map[string]bool, bool, map[int]string, bool, bool, int) {
+func (tn *Table) asdFind(td_k string, matchCount int, weightMap map[string]map[string]interface{}, matchMap map[string]map[string]bool, td *TD, thisTrHasMatch bool, td_kv *u.Kv, indexMap map[int]string, iscontinue bool, reCreate bool, thidTdIndex int, isSite bool, codeSite string) (int, map[string]map[string]interface{}, map[string]map[string]bool, bool, map[int]string, bool, bool, int) {
 	for _, k := range HasOrderContactType(td_k) { //采购单位,代理机构
 		if !ContactType[k].MatchString(td_k) { //没有匹配到采购单位,代理机构
 			continue
@@ -2732,9 +2757,9 @@ func (tn *Table) asdFind(td_k string, matchCount int, weightMap map[string]map[s
 		}
 		//匹配到进行处理
 		if ContactInfoVagueReg.MatchString(td_k) {
-			thisTrHasMatch = tn.matchContactType(&matchMap, k, td_k, td_kv.Value, td, &weightMap, thisTrHasMatch,isSite,codeSite)
+			thisTrHasMatch = tn.matchContactType(&matchMap, k, td_k, td_kv.Value, td, &weightMap, thisTrHasMatch, isSite, codeSite)
 		} else if k == "采购单位" { //打标签,权重高的重新覆盖
-			kvTags := GetKvTags([]*u.Kv{td_kv}, "", []string{"采购单位"},isSite,codeSite)
+			kvTags := GetKvTags([]*u.Kv{td_kv}, "", []string{"采购单位"}, isSite, codeSite)
 			tagVal, weightVal := u.FirstKeyValueInMap(kvTags)
 			if tagVal == k {
 				if weightMap[k][k] == nil || (weightVal != nil && weightVal.(int) >= weightMap[k][k].(int)) || len(matchMap[k]) == 0 {
@@ -2785,13 +2810,13 @@ func (tn *Table) asdFind(td_k string, matchCount int, weightMap map[string]map[s
 }
 
 //匹配到进行处理
-func (tn *Table) matchContactType(matchMap *map[string]map[string]bool, k string, td_k string, td_v string, td *TD, weightMap *map[string]map[string]interface{}, thisTrHasMatch bool,isSite bool,codeSite string) bool {
+func (tn *Table) matchContactType(matchMap *map[string]map[string]bool, k string, td_k string, td_v string, td *TD, weightMap *map[string]map[string]interface{}, thisTrHasMatch bool, isSite bool, codeSite string) bool {
 	if (*matchMap)[k] == nil {
 		(*matchMap)[k] = map[string]bool{}
 	}
 	isAddToMatchMap := true
 	if !strings.HasSuffix(td_k, "方式") {
-		kvTags := GetKvTags([]*u.Kv{&u.Kv{Key: td_k, Value: td_v}}, "", BuyerContacts,isSite,codeSite)
+		kvTags := GetKvTags([]*u.Kv{&u.Kv{Key: td_k, Value: td_v}}, "", BuyerContacts, isSite, codeSite)
 		if len(kvTags) == 1 {
 			tagVal, weightVal := u.FirstKeyValueInMap(kvTags)
 			if tagVal == "采购单位联系人" && ContactBuyerPersonFilterReg.MatchString(td_v) {

+ 6 - 4
src/jy/pretreated/division.go

@@ -597,7 +597,6 @@ func divisionPackageChild(blockPackage *map[string]*util.BlockPackage, content,
 		if len(pkg) == 1 && strings.HasSuffix(con, v[0]) {
 			return false, ""
 		}
-		//
 		is := regexp.MustCompile(v[0]+"[::]*").FindAllStringIndex(con, -1)
 		for _, sv := range is {
 			appendWarpIndex = append(appendWarpIndex, sv[0])
@@ -731,6 +730,7 @@ func divisionPackageChild(blockPackage *map[string]*util.BlockPackage, content,
 					Type:     bv[1],
 					Accuracy: accuracy,
 				}
+				//fmt.Println(text)
 				finalKv := GetKVAll(strings.TrimLeft(text, headKey), "", nil, 4,isSite,codeSite)
 				if headKey != "" {
 					kvAgain := GetKVAll(text, "", nil, 4,isSite,codeSite)
@@ -785,10 +785,12 @@ func interceptText(indexs []int, indexPkgMap map[int]string, pkgIndexMap map[str
 		} else {
 			text = con[iv:]
 		}
+		//fmt.Println(text)
 		tmptext := text
-		if strings.Contains(text, "、") {
-			text = strings.Split(text, "、")[0]
-		} else if strings.Contains(text, "\n") {
+		//if strings.Contains(text, "、") {
+		//	text = strings.Split(text, "、")[0]
+		//} else
+		if strings.Contains(text, "\n") {
 			texts := strings.Split(text, "\n")
 			text2 :=""
 			if ik+1 < len(indexs)-1 {

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

@@ -126,7 +126,7 @@ type Segment struct {
 
 //包
 type BlockPackage struct {
-	Origin   string                   //包的原始值
+	Origin      string                   //包的原始值
 	Name        string                   //标段(包)名称
 	Text        string                   //包文 (包对应的正文)
 	Budget      float64                  //标段(包)预算

+ 1 - 0
src/main_blocktest.go

@@ -84,6 +84,7 @@ func com(doc map[string]interface{}) {
 	e.InitRuleCore(false)
 	e.InitRuleCore(true)
 	e.InitBlockRule()
+	e.InitPkgCore()
 	e.InitTag(false)
 	e.InitTag(true)
 	e.InitClearFn(false)

+ 7 - 3
src/web/templates/admin/pkg_info.html

@@ -85,9 +85,13 @@ $(function () {
 				}
 				return tmp
 			}},
-			{"data":"_id",render:function(val,a,row){
-				return '<a class="btn btn-sm btn-success" href="/admin/pkglogic?vid={{.vid}}&pid='+val+'">配置逻辑</a>'
-			}},
+			{"data":"_id","width":"25%",render:function(val,a,row){
+					tmp = '<div class="btn-group">'+
+							'<a class="btn btn-sm btn-success" href="/admin/version/pkglogicore?vid={{.vid}}&s_field='+row.s_field+'&sid='+row._id+'">抽取规则</a>'+
+							'<a class="btn btn-sm btn-info" href="/admin/pkglogicback?vid={{.vid}}&s_field='+row.s_field+'&sid='+row._id+'">后置规则</a>'+
+							'</div>';
+					return  tmp
+				}},
 			{"data":"_id",render:function(val,a,row){
 				return '<a class="btn btn-sm btn-primary opr" opr="edit">编辑</a>&nbsp;<a class="btn btn-sm btn-danger" href="#" onclick="del(\''+val+'\')">删除</a>'
 			}}

+ 10 - 12
src/web/templates/admin/pkg_logicbacklist.html

@@ -9,13 +9,11 @@
 	<section class="content-header">
 		<h1>
 			<small><a class="btn btn-primary opr" opr="new">新增正则</a></small>
-			<small><a class="btn btn-primary opr" opr="newlua">新增脚本</a></small>
 		</h1>
 		<ol class="breadcrumb">
 		  <li><a href="/admin/version"><i class="fa fa-dashboard"></i>版本管理</a></li>
-		  <li><a href="/admin/version/pkginfo?vid={{.vid}}&pid={{.pid}}">分包属性</a></li>
-		  <li><a href="/admin/pkglogic?vid={{.vid}}&pid={{.pid}}">抽取逻辑</a></li>
-		  <li class="active"><a href="/admin/pkglogicback?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}">后置规则</a></li>
+		  <li><a href="/admin/version/pkginfo?vid={{.vid}}">分包属性</a></li>
+		  <li class="active"><a href="/admin/pkglogicback?vid={{.vid}}&s_field={{.s_field}}&sid={{.sid}}">后置规则</a></li>
 		</ol>
     </section>
   <!-- Main content -->
@@ -61,7 +59,7 @@ $(function () {
 		"ajax": {
 			"url": "/admin/pkglogicback/data",
 			"type": "post",
-			"data":{"vid":{{.vid}},"pid":{{.pid}},"sid":{{ .sid}} }
+			"data":{"vid":{{.vid}},"s_field":{{.s_field}},"sid":{{ .sid}} }
 		 },
 		"language": {
             "url": "/res/dist/js/dataTables.chinese.lang"
@@ -119,7 +117,7 @@ $(function () {
 								if (bcon){								
 									$.post("/admin/pkglogicback/save",obj,function(data){
 										if(data&&data.rep){
-											window.location.href="/admin/pkglogicback?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}"								
+											window.location.href="/admin/pkglogicback?vid={{.vid}}&s_field={{.s_field}}&sid={{.sid}}"
 										}else{
 											showTip(data.msg,1000)
 										}
@@ -140,9 +138,9 @@ $(function () {
 			case "new":
 				comtag=[{label:"名称",s_label:"s_name",placeholder:"",must:true},{label:"描述",s_label:"s_descript",type:"tpl_text"}]
 				regtag=[{label:"字段",s_label:"s_field",type:"tpl_list_local",url:"/admin/getfields",default:{{.field}}},{label:"正则",s_label:"s_rule",type:"tpl_text",must:true}]
-				luatag=[{label:"脚本",s_label:"s_luascript",type:"tpl_text",must:true}]
+				luatag=[{label:"脚本",s_label:"s_field",type:"tpl_list_local",url:"/admin/getfields",default:{{.field}}},{label:"脚本",s_label:"s_luascript",type:"tpl_text",must:true}]
 				testcon=[{label:"测试内容",s_label:"s_testcon",type:"tpl_text",must:true}]
-				hiddentag=[{s_label:"_id",type:"tpl_hidden"},{s_label:"vid",type:"tpl_hidden"},{s_label:"pid",type:"tpl_hidden"},{s_label:"sid",type:"tpl_hidden"},{s_label:"s_type",type:"tpl_hidden"}]
+				hiddentag=[{s_label:"_id",type:"tpl_hidden"},{s_label:"vid",type:"tpl_hidden"},{s_label:"s_field",type:"tpl_hidden"},{s_label:"sid",type:"tpl_hidden"},{s_label:"s_type",type:"tpl_hidden"}]
 				islua=false
 				tag = com.pushArry(tag,comtag)
 				if(n=="edit"){
@@ -179,7 +177,7 @@ $(function () {
 					tag = com.pushArry(tag,hiddentag)
 					check=[{label:"测试",class:"btn-warning",
 								fun:function(){
-									window.location.href="/admin/check/lua/pkgcoreback?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}&s_code="+obj.s_code
+									window.location.href="/admin/check/lua/pkgcoreback?vid={{.vid}}&s_field={{.s_field}}&sid={{.sid}}&s_code="+obj.s_code
 								}
 							}]
 					bts = com.pushArry(bts,check)
@@ -187,12 +185,12 @@ $(function () {
 					_tit="新增规则"
 					if(n=="newlua"){
 						_tit="新增脚本"
-						obj={"s_luascript":"--code脚本代码,result 抽取结果,过滤后返回result,对象结构不可改变\nfunction main(code,result)\n\t--过滤操作\n\treturn result\nend","vid":"{{.vid}}","pid":"{{.pid}}","sid":"{{.sid}}","s_type":"1"}
+						obj={"s_luascript":"--code脚本代码,result 抽取结果,过滤后返回result,对象结构不可改变\nfunction main(code,result)\n\t--过滤操作\n\treturn result\nend","vid":"{{.vid}}","s_field":"{{.s_field}}","sid":"{{.sid}}","s_type":"1"}
 						tag = com.pushArry(tag,luatag)
 						tag = com.pushArry(tag,hiddentag)
 						islua=true
 					}else{
-						obj={"vid":"{{.vid}}","pid":"{{.pid}}","sid":"{{.sid}}","s_type":"0"}
+						obj={"vid":"{{.vid}}","s_field":"{{.s_field}}","sid":"{{.sid}}","s_type":"0"}
 						tag = com.pushArry(tag,regtag)
 						tag = com.pushArry(tag,hiddentag)
 					}
@@ -218,7 +216,7 @@ function del(_id){
 			data:{"_id":_id},
 			success:function(r){
 				if(r.rep){				
-					window.location.href="/admin/pkglogicback?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}"
+					window.location.href="/admin/pkglogicback?vid={{.vid}}&s_field={{.s_field}}&sid={{.sid}}"
 				}else{
 					showTip("删除失败", 1000);
 				}

+ 0 - 198
src/web/templates/admin/pkg_logiclist.html

@@ -1,198 +0,0 @@
-{{template "inc"}}
-<!-- Main Header -->
-{{template "header"}}
-<!-- Left side column. 权限菜单 -->
-{{template "memu"}}
-
-<!-- Content Wrapper. Contains page content -->
-<div class="content-wrapper">
-	<section class="content-header">
-		<h1>
-			<small><a class="btn btn-primary opr" opr="new">新增逻辑</a></small>
-		</h1>
-		<ol class="breadcrumb">
-		  <li><a href="/admin/version"><i class="fa fa-dashboard"></i>版本管理</a></li>
-		  <li class="active"><a href="/admin/version/pkginfo?vid={{.vid}}">分包属性</a></li>
-		  <li class="active"><a href="/admin/pkglogic?vid={{.vid}}&pid={{.pid}}">抽取逻辑</a></li>
-		</ol>
-    </section>
-  <!-- Main content -->
-  <section class="content">
-      <div class="row">
-	      <div class="col-xs-12">
-	        <div class="box">
-		        <div class="box-body">
-		            <table id="dataTable" class="table table-bordered table-hover">
-		              <thead>
-		              <tr>
-						<th>名称</th>
-						<th>创建人</th>
-						<th>描述</th>
-						<th>是否启用</th>
-						<th>配置规则</th>
-						<th>操作</th>
-		              </tr>
-		              </thead>
-		            </table>
-		        </div>
-	          <!-- /.box-body -->
-	        </div>
-        <!-- /.box -->
-		</div>
-	</div>
-  </section>
-</div>
-{{template "luares"}}
-{{template "dialog"}}
-{{template "footer"}}
-
-<script>
-menuActive("version")
-$(function () {
-	ttable=$('#dataTable').DataTable({
-		"paging"      : false,
-		"lengthChange": false,
-		"searching"   : true,
-		"ordering"    : false,
-		"info"        : true,
-		"autoWidth"   : false,
-		"ajax": {
-			"url": "/admin/pkglogic/data",
-			"type": "post",
-			"data":{"vid":{{ .vid}} ,"pid":{{ .pid}} }
-		 },
-		"language": {
-            "url": "/res/dist/js/dataTables.chinese.lang"
-        },
-		"columns": [
-			{ "data": "s_name"},
-			{ "data": "s_username"},
-			{ "data": "s_descript"},
-			{ "data": "isuse",render:function(val,a,row){
-				tmp=""
-				if(val){
-					tmp="<a href='#' title='停用' onclick='use(\""+row._id+"\",false)'><i class='fa fa-fw fa-circle text-green'></i></a>已启用"
-				}else{
-					tmp="<a href='#' title='启用' onclick='use(\""+row._id+"\",true)'><i class='fa fa-fw fa-circle text-red'></i></a>未启用"
-				}
-				return tmp
-			}},
-			{"data":"_id","width":"25%",render:function(val,a,row){
-				tmp = '<div class="btn-group">'+
-					'<a class="btn btn-sm btn-info" href="/admin/pkglogicback?vid='+{{.vid}}+'&pid='+{{.pid}}+'&sid='+row._id+'">后置规则</a>'+
-					'</div>';
-				return  tmp
-			}},
-			{"data":"s_version","width":"15%",render:function(val,a,row,pos){
-				return '<a class="btn btn-sm btn-primary opr" opr="edit" row="'+pos.row+'" >编辑</a>'+
-					'&nbsp;&nbsp;<a class="btn btn-sm btn-warning" onclick="del(\''+row._id+'\')">删除</a>';
-			}}
-       	]
-	});
-	ttable.on('init.dt', function () {
-		$(".opr").click(function(){
-			var n=$(this).attr("opr")
-			var htmlObj={},obj,tag=[]
-			var _tit="" 
-			switch(n){
-			case "edit":			
-				obj=ttable.row($(this).closest("tr")).data()
-			case "editlua":
-				obj=ttable.row($(this).closest("tr")).data()
-			case "new":
-				tag=[{label:"名称",s_label:"s_name",placeholder:"",must:true},
-					{label:"描述",s_label:"s_descript",type:"tpl_text"},
-					{label:"启用",s_label:"isuse",type:"tpl_list_local",list:[{"s_name":"是","_id":true},{"s_name":"否","_id":false}],default:true},
-					{label:"标题抽取",s_label:"extfrom",type:"tpl_list_local",list:[{"s_name":"是","_id":true},{"s_name":"否","_id":false}],default:false},
-					{label:"是否适用",s_label:"s_luascript",type:"tpl_text",must:true},
-					{s_label:"_id",type:"tpl_hidden"},
-					{s_label:"vid",type:"tpl_hidden"},{s_label:"pid",type:"tpl_hidden"}]
-				if(n=="edit"){
-					_tit="编辑-"+obj.s_name
-				}else{
-					_tit="新增逻辑"
-					obj={"s_luascript":"function logic(doc)\n\treturn true\nend","vid":"{{.vid}}","pid":"{{.pid}}","s_type":"0"}
-				}
-				
-				htmlObj={
-					title:_tit,
-					tag:tag,
-					lua:true,
-					bts:[
-						{label:"保存",class:"btn-primary",
-							fun:function(){
-								var obj={}
-								var bcon=true
-								$("#_con").find("input[id!=s_show],textarea").each(function(i,el){
-									var val=$(el).val();
-									if(el.id=="s_luascript"){
-										val=editor_1.getValue()
-										obj[el.id]=val
-									}else{
-										obj[el.id]=$(el).val()
-									}
-									if(el.id!="_id"&&$(el).attr("must")&&!val){
-										bcon=false
-										return false
-									}
-								})
-								if (bcon){								
-									$.post("/admin/pkglogic/save",obj,function(data){
-										if(data&&data.rep){
-											window.location.href="/admin/pkglogic?vid={{.vid}}&pid={{.pid}}"	
-										}else{
-											showTip(data.msg,1000)
-										}
-									},'json')
-								}else{
-									alert("红色标签的表单不能为空!")
-								}
-							}
-						}
-					]
-				}
-			OpenDialog(htmlObj,obj)
-			break;
-			}
-		});
-	})
-})
-function del(_id){
-	showConfirm("确定删除?", function() {
-		$.ajax({
-			url:"/admin/pkgrulelogic/del",
-			type:"post",
-			data:{"_id":_id},
-			success:function(r){
-				if(r.rep){				
-					window.location.href="/admin/pkglogic?vid={{.vid}}&pid={{.pid}}";
-				}else{
-					showTip("删除失败", 1000);
-				}
-			}
-		})
-	});
-}
-function use(_id,utype){
-	smg=""
-	if(utype){
-		smg="确定启用?"
-	}else{
-		smg="确定停用?"
-	}
-	showConfirm(smg, function() {
-		$.ajax({
-			url:"/admin/pkglogic/use",
-			type:"post",
-			data:{"_id":_id,"isuse":utype},
-			success:function(r){
-				if(r.rep){				
-					window.location.href="/admin/pkglogic?vid={{.vid}}&pid={{.pid}}"
-				}else{
-					showTip("启用失败", 1000, function() {});
-				}
-			}
-		})
-	});
-}
-</script>

+ 308 - 0
src/web/templates/admin/pkg_logicore.html

@@ -0,0 +1,308 @@
+{{template "inc"}}
+<!-- Main Header -->
+{{template "header"}}
+<!-- Left side column. 权限菜单 -->
+{{template "memu"}}
+
+<!-- Content Wrapper. Contains page content -->
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1>
+            <small><a class="btn btn-primary opr" opr="new">新增正则</a></small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="/admin/version"><i class="fa fa-dashboard"></i>版本管理</a></li>
+            <li><a href="/admin/version/pkginfo?vid={{.vid}}">分包属性</a></li>
+            <li class="active"><a
+                        href="/admin/version/pkglogicore?vid={{.vid}}&sid={{.sid}}&s_field={{.field}}">抽取规则</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="row">
+            <div class="col-xs-12">
+                <div class="box">
+                    <div class="box-body">
+                        <table id="dataTable" class="table table-bordered table-hover">
+                            <thead>
+                            <tr>
+                                <th>代码</th>
+                                <th>名称</th>
+                                <th>创建人</th>
+                                <th>描述</th>
+                                <th>类型</th>
+                                <th>是否启用</th>
+                                <th>操作</th>
+                            </tr>
+                            </thead>
+                        </table>
+                    </div>
+                    <!-- /.box-body -->
+                </div>
+                <!-- /.box -->
+            </div>
+        </div>
+    </section>
+    <!--
+    <div class="form-group"><select class="form-control select2" multiple="multiple" data-placeholder="Select a State" style="width: 100%;"><option>Alabama</option><option>Alaska</option></select></div>
+    -->
+</div>
+{{template "luares"}}
+{{template "dialog"}}
+{{template "footer"}}
+
+<script>
+    $('.select2').select2()
+    menuActive("version")
+    $(function () {
+        ttable = $('#dataTable').DataTable({
+            "paging": false,
+            "lengthChange": false,
+            "searching": true,
+            "ordering": false,
+            "info": true,
+            "autoWidth": false,
+            "ajax": {
+                "url": "/admin/version/pkglogicore/data",
+                "type": "post",
+                "data": {"s_field":{{.field}},"vid":{{.vid}}, "sid":{{ .sid}} },
+            },
+            "language": {
+                "url": "/res/dist/js/dataTables.chinese.lang"
+            },
+            "columns": [
+                {"data": "s_code"},
+                {"data": "s_name"},
+                {"data": "s_username"},
+                {"data": "s_descript"},
+                {
+                    "data": "s_type", render: function (val, a, row) {
+                        if (val == "0") {
+                            return "正则"
+                        } else {
+                            return "lua脚本"
+                        }
+                    }
+                },
+                {
+                    "data": "isuse", render: function (val, a, row) {
+                        tmp = ""
+                        if (val) {
+                            tmp = "<a href='#' title='停用' onclick='use(\"" + row._id + "\",false)'><i class='fa fa-fw fa-circle text-green'></i></a>已启用"
+                        } else {
+                            tmp = "<a href='#' title='启用' onclick='use(\"" + row._id + "\",true)'><i class='fa fa-fw fa-circle text-red'></i></a>未启用"
+                        }
+                        return tmp
+                    }
+                },
+                {
+                    "data": "_id", render: function (val, a, row, pos) {
+                        tmp = ""
+                        if (row.s_type == "0") {
+                            tmp = '<div>' +
+                                '<a class="btn btn-sm btn-primary opr" opr="edit" row="' + pos.row + '" >编辑</a> ' +
+                                '<a class="btn btn-sm btn-warning" onclick="del(\'' + val + '\')">删除</a> ' +
+                                '</div>';
+                        } else {
+                            tmp = '<div>' +
+                                '<a class="btn btn-sm btn-primary opr" opr="editlua" row="' + pos.row + '" >编辑</a> ' +
+                                '<a class="btn btn-sm btn-warning" onclick="del(\'' + val + '\')">删除</a> ' +
+                                '</div>';
+                        }
+                        return tmp
+                    }
+                }
+            ]
+        });
+        ttable.on('init.dt', function () {
+            $(".opr").click(function () {
+                var n = $(this).attr("opr")
+                var htmlObj = {}, obj, tag = []
+                var bts = [{
+                    label: "保存", class: "btn-primary",
+                    fun: function () {
+                        var obj = {}
+                        var bcon = true
+                        $("#_con").find("input[id!=s_show],textarea").each(function (i, el) {
+                            var val = $(el).val();
+                            if (el.id == "s_luascript") {
+                                val = editor_1.getValue()
+                                obj[el.id] = val
+                            } else {
+                                obj[el.id] = $(el).val()
+                            }
+                            if (el.id != "_id" && $(el).attr("must") && !val) {
+                                bcon = false
+                                return false
+                            }
+                        })
+                        if (bcon) {
+                            $.post("/admin/version/pkglogicore/save", obj, function (data) {
+                                if (data && data.rep) {
+                                    window.location.href = "/admin/version/pkglogicore?vid={{.vid}}&sid={{.sid}}&s_field={{.field}}"
+                                } else {
+                                    showTip(data.msg, 1000)
+                                }
+                            }, 'json')
+                        } else {
+                            alert("红色标签的表单不能为空!")
+                        }
+                    }
+                }
+                ]
+                var _tit = ""
+                switch (n) {
+                    case "edit":
+                        obj = ttable.row($(this).closest("tr")).data();
+                    case "editlua":
+                        obj = ttable.row($(this).closest("tr")).data();
+                    case "newlua":
+                    case "new":
+                        comtag = [{label: "名称", s_label: "s_name", placeholder: "", must: true}, {
+                            label: "描述",
+                            s_label: "s_descript",
+                            type: "tpl_text"
+                        }, {
+                            label: "启用",
+                            s_label: "isuse",
+                            type: "tpl_list_local",
+                            list: [{"s_name": "是", "_id": true}, {"s_name": "否", "_id": false}],
+                            default: true
+                        }]
+                        regtag = [{
+                            label: "字段",
+                            s_label: "s_field",
+                            type: "tpl_list_local",
+                            url: "/admin/getfields",
+                            default:{{.field}}}, {label: "正则", s_label: "s_rule", type: "tpl_text", must: true}]
+                        luatag = [{
+                            label: "脚本",
+                            s_label: "s_field",
+                            type: "tpl_list_local",
+                            url: "/admin/getfields",
+                            default:{{.field}}}, {label: "脚本", s_label: "s_luascript", type: "tpl_text", must: true}]
+                        testcon = [{label: "测试内容", s_label: "s_testcon", type: "tpl_text", must: true}]
+                        hiddentag = [{s_label: "_id", type: "tpl_hidden"}, {
+                            s_label: "vid",
+                            type: "tpl_hidden"
+                        }, {s_label: "s_field", type: "tpl_hidden"}, {
+                            s_label: "sid",
+                            type: "tpl_hidden"
+                        }, {s_label: "s_type", type: "tpl_hidden"}]
+                        islua = false
+                        tag = com.pushArry(tag, comtag)
+                        if (n == "edit") {
+                            _tit = "编辑-" + obj.s_name
+                            tag = com.pushArry(tag, regtag)
+                            tag = com.pushArry(tag, hiddentag)
+                            tag = com.pushArry(tag, testcon)
+                            check = [{
+                                label: "测试", class: "btn-warning",
+                                fun: function () {
+                                    var obj = {}
+                                    var bcon = true
+                                    $("#_con").find("input[id!=s_show],textarea").each(function (i, el) {
+                                        var val = $(el).val();
+                                        obj[el.id] = $(el).val()
+                                        if (el.id != "_id" && $(el).attr("must") && !val) {
+                                            bcon = false
+                                            return false
+                                        }
+                                    })
+                                    if (bcon) {
+                                        $.post("/admin/check/extrule", obj, function (data) {
+                                            showMsg(JSON.stringify(data.rep))
+                                        }, 'json')
+                                    } else {
+                                        alert("红色标签的表单不能为空!")
+                                    }
+                                }
+                            }]
+                            bts = com.pushArry(bts, check)
+                        } else if (n == "editlua") {
+                            _tit = "编辑-" + obj.s_name
+                            islua = true
+                            tag = com.pushArry(tag, luatag)
+                            tag = com.pushArry(tag, hiddentag)
+                            check = [{
+                                label: "测试", class: "btn-warning",
+                                fun: function () {
+                                    window.location.href = "/admin/check/lua/core?vid={{.vid}}&sid={{.sid}}&s_code=" + obj.s_code
+                                }
+                            }]
+                            bts = com.pushArry(bts, check)
+                        } else {
+                            _tit = "新增规则"
+                            if (n == "newlua") {
+                                _tit = "新增脚本"
+                                obj = {
+                                    "s_luascript": "--code脚本代码,doc数据源,block块对象,kvs抽取kv对象,返回kvs对象,kvs结构不可改变\nfunction main(code,doc,block,kvs)\n\t--自定义抽取\n\treturn kvs\nend",
+                                    "vid": "{{.vid}}",
+                                    "s_field": "{{.field}}",
+                                    "sid": "{{.sid}}",
+                                    "s_type": "1"
+                                }
+
+                                tag = com.pushArry(tag, luatag)
+                                tag = com.pushArry(tag, hiddentag)
+                                islua = true
+                            } else {
+                                obj = {"vid": "{{.vid}}", "s_field":{{.field}}, "sid": "{{.sid}}", "s_type": "0"}
+                                tag = com.pushArry(tag, regtag)
+                                tag = com.pushArry(tag, hiddentag)
+                            }
+                        }
+                        htmlObj = {
+                            title: _tit,
+                            tag: tag,
+                            lua: islua,
+                            bts: bts
+                        }
+                        OpenDialog(htmlObj, obj)
+                        break;
+                }
+            });
+        })
+    })
+
+    function del(_id) {
+        showConfirm("确定删除?", function () {
+            $.ajax({
+                url: "/admin/version/pkglogicore/del",
+                type: "post",
+                data: {"_id": _id},
+                success: function (r) {
+                    if (r.rep) {
+                        window.location.href = "/admin/version/pkglogicore?vid={{.vid}}&sid={{.sid}}&s_field={{.field}}";
+                    } else {
+                        showTip("删除失败", 1000);
+                    }
+                }
+            })
+        });
+    }
+
+    function use(_id, utype) {
+        smg = ""
+        if (utype) {
+            smg = "确定启用?"
+        } else {
+            smg = "确定停用?"
+        }
+        showConfirm(smg, function () {
+            $.ajax({
+                url: "/admin/version/pkglogicore/use",
+                type: "post",
+                data: {"_id": _id, "isuse": utype},
+                success: function (r) {
+                    if (r.rep) {
+                        window.location.reload()
+                    } else {
+                        showTip("启用失败", 1000, function () {
+                        });
+                    }
+                }
+            })
+        });
+    }
+</script>