소스 검색

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

zhangjinkun 6 년 전
부모
커밋
4d84be6002

+ 1 - 1
src/config.json

@@ -10,7 +10,7 @@
     "mergetablealias": "projectset_v1",
     "saveresult": false,
     "fieldscore": true,
-    "qualityaudit": false,
+    "qualityaudit": true,
     "iscltlog": false,
     "brandgoods": true,
     "udptaskid": "5be107e600746bf92debf080",

+ 31 - 34
src/jy/admin/audit/dataaudit.go

@@ -19,11 +19,10 @@ func init() {
 		//s_coll := c.Query("s_coll")
 		c.HTML(200, "audit_auditone.html", gin.H{"name": name})
 	})
-	Admin.POST("/audit/auditone", AuditOne)
+	Admin.POST("/audit/auditonefield", AuditOneField)
 	Admin.POST("/audit/buyerclass", BuyerClass) //采购单位分类
 	Admin.POST("/audit/addsave", AddSave)       //新增
 	Admin.POST("/audit/auditsave", AuditSave)   //保存
-
 }
 
 func AuditData(c *gin.Context) {
@@ -46,31 +45,23 @@ func AuditData(c *gin.Context) {
 	}
 }
 
-func AuditOne(c *gin.Context) {
-	name, _ := c.GetPostForm("name")
-	coll, _ := c.GetPostForm("s_coll")
-	source, _ := c.GetPostForm("source")
+func AuditOneField(c *gin.Context) {
+	field, _ := c.GetPostForm("field")
 	limitstr, _ := c.GetPostForm("length")
 	startstr, _ := c.GetPostForm("start")
 	start, _ := strconv.Atoi(startstr)
 	limit, _ := strconv.Atoi(limitstr)
-	query := make(map[string]interface{})
-	if source == "-1" && coll != "" { //外层
-		query = map[string]interface{}{
-			name + "_err": map[string]interface{}{
-				"$exists": true,
-			},
-			name + "_isaudit": false,
-		}
-		data, _ := Mgo.Find(coll, query, `{"_id":-1}`, nil, false, start, limit)
-		count := Mgo.Count(coll, query)
-		for _, d := range *data {
-			d["name"] = d[name]
-		}
-		c.JSON(200, gin.H{"data": data, "recordsFiltered": count, "recordsTotal": count})
-	} else { //分包
-		c.JSON(200, gin.H{"data": map[string]interface{}{}, "recordsFiltered": 0, "recordsTotal": 0})
+	query := map[string]interface{}{
+		"field":     field,
+		"ispackage": false,
+	}
+	data, _ := Mgo.Find("audit_err", query, `{"_id":-1}`, nil, false, start, limit)
+	for _, d := range *data {
+		timeStr := time.Unix(d["l_createtime"].(int64), 0).Format(Date_Short_Layout)
+		d["l_createtime"] = timeStr
 	}
+	count := Mgo.Count("audit_err", query)
+	c.JSON(200, gin.H{"data": data, "recordsFiltered": count, "recordsTotal": count})
 }
 
 func BuyerClass(c *gin.Context) {
@@ -102,9 +93,10 @@ func AddSave(c *gin.Context) {
 
 func AuditSave(c *gin.Context) {
 	field, _ := c.GetPostForm("field")
-	name, _ := c.GetPostForm("name")
-	_id, _ := c.GetPostForm("id")
 	coll, _ := c.GetPostForm("coll")
+	name, _ := c.GetPostForm("val")
+	_id, _ := c.GetPostForm("id")
+	eid, _ := c.GetPostForm("eid")
 	update := make(map[string]interface{})
 	if field == "buyer" || field == "winner" { //更新buyer或winner库,并保存到redis
 		if field == "buyer" {
@@ -117,27 +109,32 @@ func AuditSave(c *gin.Context) {
 		update["pici"] = time.Now().Unix()
 		update["s_source"] = "抽取"
 		//更新结果表数据
-		b1 := Mgo.UpdateById(coll, _id, map[string]interface{}{
+		b1 := Mgo.UpdateById(coll, eid, map[string]interface{}{
 			"$set": map[string]interface{}{
-				field + "_isaudit": true,
-				field:              name,
+				field: name,
 			},
 		})
+		log.Println("update coll", coll, "id", eid, field, "after audit", b1)
 		//更新原有的winner或buyer库
 		b2 := Mgo.Update(field, `{"name":"`+name+`"}`, map[string]interface{}{
 			"$set": update}, true, false)
-		log.Println("Audit--Update "+field, b2)
+		log.Println("Audit--Update ", field, "coll", b2)
 		//更新redis
-		p := redis.PutCKV(field, field+"_"+name, 1)
-		log.Println("Audit--Update "+field+" redis:", p)
+		b3 := redis.PutCKV(field, field+"_"+name, 1)
+		log.Println("Audit--Update ", field, " redis:", b3)
+		//删除audit_err数据
+		b4 := Mgo.Del("audit_err", `{"_id":"`+_id+`"}`)
+		log.Println("Del audit_err id", _id, b4)
 		c.JSON(200, gin.H{"rep": b1})
 	} else {
-		b3 := Mgo.UpdateById(coll, _id, map[string]interface{}{
+		b5 := Mgo.UpdateById(coll, eid, map[string]interface{}{
 			"$set": map[string]interface{}{
-				field + "_isaudit": true,
-				field:              name,
+				field: name,
 			},
 		})
-		c.JSON(200, gin.H{"rep": b3})
+		//删除audit_err数据
+		b4 := Mgo.Del("audit_err", `{"_id":"`+_id+`"}`)
+		log.Println("Del audit_err id", _id, b4)
+		c.JSON(200, gin.H{"rep": b5})
 	}
 }

+ 38 - 15
src/jy/admin/rulecheck.go

@@ -286,7 +286,7 @@ func checkCoreReg(field, content, ruleText string) map[string]string {
 //lua脚本前置过滤验证
 func checkPreScript(code, name, infoid, script string) map[string]interface{} {
 	doc, _ := Mgo.FindById("bidding", infoid, extract.Fields)
-	j,_ := extract.PreInfo(*doc)
+	j, _ := extract.PreInfo(*doc)
 	delete(*j.Data, "contenthtml")
 	lua := ju.LuaScript{Code: code, Name: name, Doc: *j.Data, Script: script}
 	lua.Block = j.Block
@@ -306,28 +306,51 @@ func checkBackScript(table, code, name, version, infoid, script string, alone bo
 	e.InitRuleCore()
 	e.InitTag()
 	tmp, _ := Mgo.FindById("bidding", infoid, extract.Fields)
-	j,_ := extract.PreInfo(*tmp)
+	j, _ := extract.PreInfo(*tmp)
 	doc := *j.Data
 	//全局前置规则,结果覆盖doc属性
 	for _, v := range e.RulePres {
 		doc = extract.ExtRegPre(doc, j, v, e.TaskInfo)
 	}
 	//抽取规则
-	for _, vc := range e.RuleCores {
-		tmp := ju.DeepCopy(doc).(map[string]interface{})
-		//是否进入逻辑
-		if !ju.Logic(vc.LuaLogic, tmp) {
-			continue
-		}
-		//抽取-前置规则
-		for _, v := range vc.RulePres {
-			tmp = extract.ExtRegPre(tmp, j, v, e.TaskInfo)
+	if j.CategorySecond==""{
+		for _, vc1 := range e.RuleCores[j.Category] {
+			for _, vc := range vc1 {
+				tmp := ju.DeepCopy(doc).(map[string]interface{})
+				//是否进入逻辑
+				if !ju.Logic(vc.LuaLogic, tmp) {
+					continue
+				}
+				//抽取-前置规则
+				for _, v := range vc.RulePres {
+					tmp = extract.ExtRegPre(tmp, j, v, e.TaskInfo)
+				}
+				//抽取-规则
+				for _, v := range vc.RuleCores {
+					extract.ExtRegCore(vc.ExtFrom, tmp, j, v, e)
+				}
+			}
 		}
-		//抽取-规则
-		for _, v := range vc.RuleCores {
-			extract.ExtRegCore(vc.ExtFrom, tmp, j, v, e)
+	}else{
+		for _, vc1 := range e.RuleCores[j.Category+"_"+j.CategorySecond] {
+			for _, vc := range vc1 {
+				tmp := ju.DeepCopy(doc).(map[string]interface{})
+				//是否进入逻辑
+				if !ju.Logic(vc.LuaLogic, tmp) {
+					continue
+				}
+				//抽取-前置规则
+				for _, v := range vc.RulePres {
+					tmp = extract.ExtRegPre(tmp, j, v, e.TaskInfo)
+				}
+				//抽取-规则
+				for _, v := range vc.RuleCores {
+					extract.ExtRegCore(vc.ExtFrom, tmp, j, v, e)
+				}
+			}
 		}
 	}
+
 	result := extract.GetResultMapForLua(j)
 	lua := ju.LuaScript{Code: code, Name: name, Result: result, Script: script}
 	lua.Block = j.Block
@@ -350,7 +373,7 @@ func checkBackScript(table, code, name, version, infoid, script string, alone bo
 //lua脚本抽取验证
 func checkCoreScript(code, name, infoid, script string) interface{} {
 	doc, _ := Mgo.FindById("bidding", infoid, extract.Fields)
-	j ,_ := extract.PreInfo(*doc)
+	j, _ := extract.PreInfo(*doc)
 	delete(*j.Data, "contenthtml")
 	lua := ju.LuaScript{Code: code, Name: name, Doc: *j.Data, Script: script}
 	lua.Block = j.Block

+ 208 - 0
src/jy/admin/user.go

@@ -13,6 +13,7 @@ import (
 	"github.com/gin-contrib/sessions"
 	"github.com/gin-gonic/gin"
 	"gopkg.in/mgo.v2/bson"
+	"fmt"
 )
 
 func init() {
@@ -25,6 +26,9 @@ func init() {
 	Admin.GET("/menu", func(c *gin.Context) {
 		c.HTML(http.StatusOK, "menu.html", gin.H{})
 	})
+	Admin.GET("/infotype", func(c *gin.Context) {
+		c.HTML(http.StatusOK, "class.html", gin.H{})
+	})
 	Admin.GET("/role", func(c *gin.Context) {
 		c.HTML(http.StatusOK, "role.html", gin.H{})
 	})
@@ -46,6 +50,13 @@ func init() {
 	Admin.POST("/menu/data", MenuData)
 	Admin.POST("/menu/searchbyid", MenuSearchById)
 	Admin.POST("/menu/del", MenuDel)
+	Admin.POST("/infotype/data", InfotypeData)
+	Admin.POST("/fields/data", FieldsData)
+	Admin.POST("/topclass/data", TopclassData)
+	Admin.POST("/subclass/data", SubclassData)
+	Admin.POST("/infotype/save", InfotypeSave)
+	Admin.POST("/infotype/select", InfotypeSelect)
+	Admin.POST("/infotype/del", InfotypeDel)
 	Admin.POST("/role/menu/data", RoleMenuData)
 	Admin.POST("/role/menu/save", RoleMenuSave)
 	Admin.POST("/role/select", RoleSelect)
@@ -84,6 +95,203 @@ func SecondMenuData(c *gin.Context) {
 	data, _ := Mgo.Find("menusecond", maps, nil, nil, false, -1, -1)
 	c.JSON(200, gin.H{"data": data})
 }
+func InfotypeData(c *gin.Context) {
+	datas, _ := Mgo.Find("infotype", `{}`, nil, nil, false, -1, -1)
+	list:=[]map[string]interface{}{}
+	for _,data:=range *datas{
+		if data["subclass"]==nil{
+			data["subclass"]=""
+			list=append(list,data)
+		}else{
+			for k,_:=range data["subclass"].(map[string]interface{}){
+				value:=map[string]interface{}{
+					"_id":data["_id"],
+					"topclass":data["topclass"],
+					"subclass":k,
+				}
+				list=append(list,value)
+			}
+		}
+	}
+	c.JSON(200, gin.H{"data": list})
+}
+func FieldsData(c *gin.Context){
+	datas, _ := Mgo.Find("fields", `{}`, nil, nil, false, -1, -1)
+	c.JSON(200, gin.H{"data": datas})
+}
+func TopclassData(c *gin.Context){
+	datas, _ := Mgo.Find("infoclass", `{}`, nil, nil, false, -1, -1)
+	c.JSON(200, gin.H{"data": datas})
+}
+func SubclassData(c *gin.Context){
+	topclass, _ := c.GetPostForm("top")
+	datas, _ := Mgo.FindOneByField("infoclass",`{"topclass":"`+topclass+`"}`,`{"subclass":"1"}`)
+	data:=*datas
+	if data["subclass"]!=nil{
+		c.JSON(200, gin.H{"data": datas})
+	}
+}
+func InfotypeSave(c *gin.Context){
+	topclass, _ := c.GetPostForm("topclass")
+	subclass, _ := c.GetPostForm("subclass")
+	fieldsStr, _ := c.GetPostForm("fields")
+	fieldsStr2, _ := c.GetPostForm("fields2")
+	_id,_:=c.GetPostForm("_id")
+	fields := make([]string, 0)
+	err := json.Unmarshal([]byte(fieldsStr), &fields)
+	fields2 := make([]string, 0)
+	err2 := json.Unmarshal([]byte(fieldsStr2), &fields2)
+	if _id=="" {
+		b := Mgo.Count("infotype", map[string]interface{}{
+			"topclass": topclass,
+		})
+		b2 := 0
+		if subclass != "" {
+			b2 = Mgo.Count("infotype", map[string]interface{}{
+				"subclass." + subclass: map[string]interface{}{
+					"$exists": true,
+				},
+			})
+		}
+		if (b == 0)||(b!=0&&b2==0&&subclass!=""){
+			if err == nil {
+				if subclass == "" {
+					maps := map[string]interface{}{
+						"topclass": topclass,
+						"fields":   map[string]interface{}{},
+					}
+					for _, field := range fields {
+						maps["fields"].(map[string]interface{})[field] = true
+					}
+					Mgo.Save("infotype", maps)
+				} else {
+					maps := map[string]interface{}{
+					}
+					for _, field := range fields {
+						maps = map[string]interface{}{
+							"subclass." + subclass + "." + field: true,
+						}
+						maps2 := map[string]interface{}{
+							"$set": maps,
+						}
+						set := map[string]interface{}{
+							"topclass": topclass,
+						}
+						Mgo.Update("infotype", set, maps2, true, false)
+					}
+				}
+				c.JSON(200, gin.H{"rep": true})
+			}
+		}
+	}else{
+		if err == nil && err2==nil{
+			set:=map[string]interface{}{
+				"_id":bson.ObjectIdHex(_id),
+			}
+			if subclass == "" {
+				maps := map[string]interface{}{
+					"fields":   map[string]interface{}{},
+				}
+				for _, field := range fields {
+					maps["fields"].(map[string]interface{})[field] = true
+				}
+				maps2:=map[string]interface{}{
+					"$set":maps,
+				}
+				Mgo.Update("infotype", set, maps2, false, false)
+			} else {
+				maps := map[string]interface{}{
+					"subclass."+subclass:map[string]interface{}{},
+				}
+				for _, field := range fields {
+					maps["subclass."+subclass].(map[string]interface{})[field] = true
+					maps2 := map[string]interface{}{
+						"$set": maps,
+					}
+					Mgo.Update("infotype", set, maps2, false, false)
+				}
+			}
+			c.JSON(200, gin.H{"rep": true})
+		}
+	}
+
+}
+func InfotypeSelect(c *gin.Context) {
+	_id, _ := c.GetPostForm("_id")
+	subclass, _ := c.GetPostForm("subclass")
+	fmt.Println(_id)
+	fmt.Println(subclass)
+	one1,_:=Mgo.FindById("infotype",_id,`{}`)
+	one:=*one1
+	datas, _ := Mgo.Find("fields", `{}`, nil, nil, false, -1, -1)
+	datas2:=*datas
+	//list2:=[]map[string]interface{}{}
+	if one["subclass"]==nil{
+		list:=[]interface{}{}
+		for k,v:=range one["fields"].(map[string]interface{}){
+			if v==true{
+				s_name1,_:=Mgo.FindOneByField("fields",map[string]interface{}{"s_field":k},`{}`)
+				s_name:=*s_name1
+				//已存在属性
+				list=append(list,s_name)
+				for key,value:=range datas2{
+					if value["s_field"]==k{
+						datas2 = append(datas2[:key], datas2[key+1:]...)
+					}
+				}
+			}
+		}
+		fmt.Println(one["topclass"].(string),list)
+		c.JSON(200, gin.H{"topclass": one["topclass"].(string), "subclass": "","fields2":datas2, "fields": list})
+	}else{
+		maps:=one["subclass"].(map[string]interface{})[subclass]
+		list:=[]interface{}{}
+		for k,v:=range maps.(map[string]interface{}){
+			if v==true{
+				s_name1,_:=Mgo.FindOneByField("fields",map[string]interface{}{"s_field":k},`{}`)
+				s_name:=*s_name1
+				list=append(list,s_name)
+				for key,value:=range datas2{
+					if value["s_field"]==k{
+						datas2 = append(datas2[:key], datas2[key+1:]...)
+					}
+				}
+			}
+		}
+		fmt.Println(one["topclass"].(string),subclass,list)
+		c.JSON(200, gin.H{"topclass": one["topclass"].(string), "subclass":subclass,"fields2":datas2, "fields": list})
+	}
+
+}
+func InfotypeDel(c *gin.Context) {
+	_id, _ := c.GetPostForm("_id")
+	subclass, _ := c.GetPostForm("subclass")
+	set:=map[string]interface{}{
+		"_id":bson.ObjectIdHex(_id),
+	}
+	if subclass==""{
+		b:=Mgo.Del("infotype",set)
+		c.JSON(200, gin.H{"rep": b})
+	}else{
+		info1,_:=Mgo.FindById("infotype",_id,`{}`)
+		info:=*info1
+		maps:=info["subclass"].(map[string]interface{})
+		delete(maps,subclass)
+		if len(maps)==0{
+			b:=Mgo.Del("infotype",set)
+			c.JSON(200, gin.H{"rep": b})
+		}else{
+			maps2:=map[string]interface{}{
+				"subclass":maps,
+			}
+			maps3:=map[string]interface{}{
+				"$set":maps2,
+			}
+			b:=Mgo.Update("infotype",set,maps3,false,false)
+			c.JSON(200, gin.H{"rep": b})
+		}
+	}
+}
 func RoleMenuData(c *gin.Context) {
 	role, _ := c.GetPostForm("role")
 	maps := map[string]interface{}{

+ 75 - 9
src/jy/admin/version.go

@@ -2,15 +2,17 @@
 package admin
 
 import (
-	"github.com/gin-contrib/sessions"
-	"github.com/gin-gonic/gin"
-	"gopkg.in/mgo.v2/bson"
 	. "jy/mongodbutil"
 	"jy/util"
+	"log"
 	"net/http"
 	qu "qfw/util"
 	"strings"
 	"time"
+
+	"github.com/gin-contrib/sessions"
+	"github.com/gin-gonic/gin"
+	"gopkg.in/mgo.v2/bson"
 )
 
 func init() {
@@ -27,20 +29,20 @@ func init() {
 	})
 	//根据_id查询版本详细信息
 	Admin.GET("/version/dataById", func(c *gin.Context) {
-		gid ,b :=c.GetQuery("_id")
-		if !b || !bson.IsObjectIdHex(gid){
-			c.JSON(400,gin.H{"req":false})
+		gid, b := c.GetQuery("_id")
+		if !b || !bson.IsObjectIdHex(gid) {
+			c.JSON(400, gin.H{"req": false})
 			return
 		}
 
 		data, _ := Mgo.FindOne("version", `{"_id":"`+gid+`","delete":false}`)
-		c.JSON(200, gin.H{"req":true,"data": data})
+		c.JSON(200, gin.H{"req": true, "data": data})
 	})
 	Admin.POST("/version/save", func(c *gin.Context) {
 		_id, _ := c.GetPostForm("_id")
 		data := GetPostForm(c)
-		if data["s_filefileds"]!=nil{
-			data["s_filefileds"] = strings.Split(data["s_filefileds"].(string),",")
+		if data["s_filefileds"] != nil {
+			data["s_filefileds"] = strings.Split(data["s_filefileds"].(string), ",")
 		}
 		if _id != "" {
 			Mgo.UpdateById("version", _id, map[string]interface{}{"$set": data})
@@ -249,6 +251,70 @@ func init() {
 		//b := Mgo.Del("versioninfo", `{"_id":"`+_id+`"}`)
 		c.JSON(200, gin.H{"rep": b})
 	})
+	//分块配置
+	Admin.GET("/version/blockinfo", func(c *gin.Context) {
+		vid := c.Query("vid")
+		c.HTML(http.StatusOK, "blockinfo.html", gin.H{"vid": vid})
+	})
+	Admin.POST("/version/blockinfo_list", func(c *gin.Context) {
+		vid, _ := c.GetPostForm("vid")
+		data, _ := Mgo.Find("block_info", bson.M{"vid": vid, "delete": false}, `{"index":-1}`, `{"block_reg":1,"title_reg":1,"index":1}`, false, -1, -1)
+		for _, v := range *data {
+			v["id"] = qu.BsonIdToSId(v["_id"])
+		}
+		c.JSON(http.StatusOK, gin.H{"data": data})
+	})
+	//分块配置保存
+	Admin.POST("/version/blockinfo_save", func(c *gin.Context) {
+		status := false
+		_id, _ := c.GetPostForm("_id")
+		block_reg, _ := c.GetPostForm("block_reg")
+		title_reg, _ := c.GetPostForm("title_reg")
+		if _id != "" {
+			status = Mgo.UpdateById("block_info", _id, bson.M{
+				"$set": bson.M{
+					"l_updatetime": time.Now().Unix(),
+					"block_reg":    block_reg,
+					"title_reg":    title_reg,
+				},
+			})
+		} else {
+			vid, _ := c.GetPostForm("vid")
+			list, flag := Mgo.Find("block_info", bson.M{"vid": vid}, `{"index": 1}`, `{"index":1}`, false, 0, 1)
+			index := -1
+			if flag && len(*list) == 1 {
+				index = qu.IntAllDef((*list)[0]["index"], 1) - 1
+			}
+			status = Mgo.Save("block_info", bson.M{
+				"delete":       false,
+				"index":        index,
+				"block_reg":    block_reg,
+				"title_reg":    title_reg,
+				"vid":          vid,
+				"l_createtime": time.Now().Unix(),
+				"s_username":   sessions.Default(c).Get("username"),
+			}) != ""
+		}
+		c.JSON(http.StatusOK, gin.H{"status": status})
+	})
+	Admin.POST("/version/blockinfo_updateindex", func(c *gin.Context) {
+		_ids := c.PostFormArray("_ids")
+		indexs := c.PostFormArray("indexs")
+		log.Println(_ids, indexs)
+		for k, _id := range _ids {
+			Mgo.UpdateById("block_info", _id, bson.M{
+				"$set": bson.M{
+					"index": qu.IntAll(indexs[k]),
+				},
+			})
+		}
+		c.JSON(http.StatusOK, gin.H{})
+	})
+	Admin.POST("/version/blockinfo_delete", func(c *gin.Context) {
+		_id, _ := c.GetPostForm("_id")
+		status := Mgo.UpdateById("block_info", _id, bson.M{"$set": bson.M{"delete": true}})
+		c.JSON(http.StatusOK, gin.H{"status": status})
+	})
 }
 
 //克隆版本通用属性

+ 3 - 2
src/jy/extract/exportask.go

@@ -56,6 +56,7 @@ func extractAndExport(v string, t map[string]interface{}) {
 	e.InitRuleCore()
 	e.InitTag()
 	e.InitClearFn()
+	e.InfoTypeList()
 	//品牌抽取是否开启
 	ju.IsBrandGoods = ju.Config["brandgoods"].(bool)
 
@@ -72,9 +73,9 @@ func extractAndExport(v string, t map[string]interface{}) {
 		var j, jf *ju.Job
 		if e.IsFileField && v["projectinfo"] != nil {
 			v["isextFile"] = true
-			j, jf = PreInfo(v)
+			j, jf = e.PreInfo(v)
 		} else {
-			j, _ = PreInfo(v)
+			j, _ = e.PreInfo(v)
 		}
 		e.TaskInfo.ProcessPool <- true
 		go e.ExtractProcess(j, jf)

+ 38 - 12
src/jy/extract/extpackage.go

@@ -146,23 +146,49 @@ func PackageDetail(j *ju.Job, e *ExtractTask) {
 func extRegBackPack(j *ju.Job, e *ExtractTask) {
 	defer qu.Catch()
 	//正则清理
-	for _, rc := range e.RuleCores {
-		for pk, pack := range j.PackageInfo {
-			clear, _ := pack["clear"].(map[string]interface{})
-			for k, val := range pack {
-				if b, ok := clear[k].(bool); ok && b {
-					if rc.Field == k {
-						text := qu.ObjToString(val)
-						for _, in := range rc.RuleBacks {
-							if text != "" && !in.IsLua {
-								text = in.RegPreBac.Reg.ReplaceAllString(text, in.RegPreBac.Replace)
+	if j.CategorySecond == "" {
+		for _, rc1 := range e.RuleCores[j.Category] {
+			for _, rc := range rc1 {
+				for pk, pack := range j.PackageInfo {
+					clear, _ := pack["clear"].(map[string]interface{})
+					for k, val := range pack {
+						if b, ok := clear[k].(bool); ok && b {
+							if rc.Field == k {
+								text := qu.ObjToString(val)
+								for _, in := range rc.RuleBacks {
+									if text != "" && !in.IsLua {
+										text = in.RegPreBac.Reg.ReplaceAllString(text, in.RegPreBac.Replace)
+									}
+								}
+								pack[k] = text
 							}
 						}
-						pack[k] = text
 					}
+					j.PackageInfo[pk] = pack
+				}
+			}
+		}
+	} else {
+		for _, rc1 := range e.RuleCores[j.Category+"_"+j.CategorySecond] {
+			for _, rc := range rc1 {
+				for pk, pack := range j.PackageInfo {
+					clear, _ := pack["clear"].(map[string]interface{})
+					for k, val := range pack {
+						if b, ok := clear[k].(bool); ok && b {
+							if rc.Field == k {
+								text := qu.ObjToString(val)
+								for _, in := range rc.RuleBacks {
+									if text != "" && !in.IsLua {
+										text = in.RegPreBac.Reg.ReplaceAllString(text, in.RegPreBac.Replace)
+									}
+								}
+								pack[k] = text
+							}
+						}
+					}
+					j.PackageInfo[pk] = pack
 				}
 			}
-			j.PackageInfo[pk] = pack
 		}
 	}
 	//通用正则清理

+ 146 - 52
src/jy/extract/extract.go

@@ -83,9 +83,9 @@ func RunExtractTestTask(ext *ExtractTask, startId, num string) bool {
 			var j, jf *ju.Job
 			if ext.IsFileField && v["projectinfo"] != nil {
 				v["isextFile"] = true
-				j, jf = PreInfo(v)
+				j, jf = ext.PreInfo(v)
 			} else {
-				j, _ = PreInfo(v)
+				j, _ = ext.PreInfo(v)
 			}
 			ext.TaskInfo.ProcessPool <- true
 			go ext.ExtractProcess(j, jf)
@@ -184,9 +184,9 @@ func RunExtractTask(taskId string) {
 			var j, jf *ju.Job
 			if ext.IsFileField && v["projectinfo"] != nil {
 				v["isextFile"] = true
-				j, jf = PreInfo(v)
+				j, jf = ext.PreInfo(v)
 			} else {
-				j, _ = PreInfo(v)
+				j, _ = ext.PreInfo(v)
 			}
 			ext.TaskInfo.ProcessPool <- true
 			go ext.ExtractProcess(j, jf)
@@ -201,8 +201,13 @@ func RunExtractTask(taskId string) {
 	time.AfterFunc(1*time.Minute, func() { RunExtractTask(taskId) })
 }
 
-//信息预处理
+//信息预处理-不和版本关联,取最新版本的配置项
 func PreInfo(doc map[string]interface{}) (j, jf *ju.Job) {
+	return (&ExtractTask{}).PreInfo(doc)
+}
+
+//信息预处理-和版本关联
+func (e *ExtractTask) PreInfo(doc map[string]interface{}) (j, jf *ju.Job) {
 	defer qu.Catch()
 	//判断是否有附件这个字段
 	var isextFile bool
@@ -225,6 +230,7 @@ func PreInfo(doc map[string]interface{}) (j, jf *ju.Job) {
 		file2text(&doc) //附件文本堆一起(后期可以考虑,分开处理),方法里修改了doc["detailfile"]结果
 	}
 	toptype := qu.ObjToString(doc["toptype"])
+	subtype := qu.ObjToString(doc["subtype"])
 	if qu.ObjToString(doc["type"]) == "bid" {
 		toptype = "结果"
 	}
@@ -234,6 +240,7 @@ func PreInfo(doc map[string]interface{}) (j, jf *ju.Job) {
 	j = &ju.Job{
 		SourceMid:  qu.BsonIdToSId(doc["_id"]),
 		Category:   toptype,
+		CategorySecond:subtype,
 		Content:    qu.ObjToString(doc["detail"]),
 		SpiderCode: qu.ObjToString(doc["spidercode"]),
 		//Domain:     qu.ObjToString(doc["domain"]),
@@ -244,6 +251,7 @@ func PreInfo(doc map[string]interface{}) (j, jf *ju.Job) {
 		Province:  qu.ObjToString(doc["area"]),
 		Result:    map[string][]*ju.ExtField{},
 		BuyerAddr: qu.ObjToString(doc["buyeraddr"]),
+		RuleBlock: e.RuleBlock,
 	}
 	if isextFile {
 		jf = &ju.Job{
@@ -257,6 +265,7 @@ func PreInfo(doc map[string]interface{}) (j, jf *ju.Job) {
 			Province:   qu.ObjToString(doc["area"]),
 			Result:     map[string][]*ju.ExtField{},
 			BuyerAddr:  qu.ObjToString(doc["buyeraddr"]),
+			RuleBlock:  e.RuleBlock,
 			IsFile:     isextFile,
 		}
 	}
@@ -321,37 +330,84 @@ func (e *ExtractTask) ExtractDetail(j *ju.Job) {
 		for _, v := range e.RulePres {
 			doc = ExtRegPre(doc, j, v, e.TaskInfo)
 		}
-		//抽取规则
-		for _, vc := range e.RuleCores {
-			tmp := ju.DeepCopy(doc).(map[string]interface{})
-			//是否进入逻辑
-			if !ju.Logic(vc.LuaLogic, tmp) {
-				continue
-			}
-			//抽取-前置规则
-			for _, v := range vc.RulePres {
-				tmp = ExtRegPre(tmp, j, v, e.TaskInfo)
+		if j.CategorySecond=="" {
+			//抽取规则
+			tmprules:= map[string][]*RuleCore{}
+			lock.Lock()
+			for k, vc1 := range e.RuleCores[j.Category] {
+				tmprules[k]=vc1
 			}
-			// log.Debug("抽取-前置规则", tmp)
+			lock.Unlock()
+			for _, vc1 := range tmprules {
+				for _, vc := range vc1 {
+					tmp := ju.DeepCopy(doc).(map[string]interface{})
+					//是否进入逻辑
+					if !ju.Logic(vc.LuaLogic, tmp) {
+						continue
+					}
+					//抽取-前置规则
+					for _, v := range vc.RulePres {
+						tmp = ExtRegPre(tmp, j, v, e.TaskInfo)
+					}
+					// log.Debug("抽取-前置规则", tmp)
 
-			//抽取-规则
-			for _, v := range vc.RuleCores {
-				ExtRegCore(vc.ExtFrom, tmp, j, v, e)
-			}
-			// log.Debug("抽取-规则", tmp)
+					//抽取-规则
+					for _, v := range vc.RuleCores {
+						ExtRegCore(vc.ExtFrom, tmp, j, v, e)
+					}
+					// log.Debug("抽取-规则", tmp)
 
-			//项目名称未能抽取到,标题来凑
-			if vc.Field == "projectname" {
-				if len(j.Result[vc.Field]) < 1 {
-					j.Result[vc.Field] = append(j.Result[vc.Field], &ju.ExtField{vc.Field, "title", "title", "regexp", "title", vc.ExtFrom, j.Title, 0})
+					//项目名称未能抽取到,标题来凑
+					if vc.Field == "projectname" {
+						if len(j.Result[vc.Field]) < 1 {
+							j.Result[vc.Field] = append(j.Result[vc.Field], &ju.ExtField{vc.Field, "title", "title", "regexp", "title", vc.ExtFrom, j.Title, 0})
+						}
+					}
+
+					//抽取-后置规则
+					for _, v := range vc.RuleBacks {
+						ExtRegBack(j, v, e.TaskInfo)
+					}
+					// log.Debug("抽取-后置规则", tmp)
 				}
 			}
+		}else{
+			fmt.Println(e.RuleCores)
+			fmt.Println("++++++++++++++++")
+			fmt.Println(e.RuleCores[j.Category+"_"+j.CategorySecond])
+			for _, vc1 := range e.RuleCores[j.Category+"_"+j.CategorySecond] {
+				for _, vc := range vc1 {
+					tmp := ju.DeepCopy(doc).(map[string]interface{})
+					//是否进入逻辑
+					if !ju.Logic(vc.LuaLogic, tmp) {
+						continue
+					}
+					//抽取-前置规则
+					for _, v := range vc.RulePres {
+						tmp = ExtRegPre(tmp, j, v, e.TaskInfo)
+					}
+					// log.Debug("抽取-前置规则", tmp)
 
-			//抽取-后置规则
-			for _, v := range vc.RuleBacks {
-				ExtRegBack(j, v, e.TaskInfo)
+					//抽取-规则
+					for _, v := range vc.RuleCores {
+						ExtRegCore(vc.ExtFrom, tmp, j, v, e)
+					}
+					// log.Debug("抽取-规则", tmp)
+
+					//项目名称未能抽取到,标题来凑
+					if vc.Field == "projectname" {
+						if len(j.Result[vc.Field]) < 1 {
+							j.Result[vc.Field] = append(j.Result[vc.Field], &ju.ExtField{vc.Field, "title", "title", "regexp", "title", vc.ExtFrom, j.Title, 0})
+						}
+					}
+
+					//抽取-后置规则
+					for _, v := range vc.RuleBacks {
+						ExtRegBack(j, v, e.TaskInfo)
+					}
+					// log.Debug("抽取-后置规则", tmp)
+				}
 			}
-			// log.Debug("抽取-后置规则", tmp)
 		}
 
 		//全局后置规则
@@ -418,37 +474,75 @@ func (e *ExtractTask) ExtractFile(j *ju.Job) {
 			}
 		}
 		//抽取规则
-		for _, vc := range e.RuleCores {
-			tmp := ju.DeepCopy(doc).(map[string]interface{})
-			//是否进入逻辑
-			if !ju.Logic(vc.LuaLogic, tmp) {
-				continue
-			}
-			//抽取-前置规则
-			for _, v := range vc.RulePres {
-				if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
-					tmp = ExtRegPre(tmp, j, v, e.TaskInfo)
-				}
-			}
-			// log.Debug("抽取-前置规则", tmp)
+		if j.CategorySecond==""{
+			for _, vc1 := range e.RuleCores[j.Category] {
+				for _, vc := range vc1 {
+					tmp := ju.DeepCopy(doc).(map[string]interface{})
+					//是否进入逻辑
+					if !ju.Logic(vc.LuaLogic, tmp) {
+						continue
+					}
+					//抽取-前置规则
+					for _, v := range vc.RulePres {
+						if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
+							tmp = ExtRegPre(tmp, j, v, e.TaskInfo)
+						}
+					}
+					// log.Debug("抽取-前置规则", tmp)
+
+					//抽取-规则
+					for _, v := range vc.RuleCores {
+						if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
+							ExtRegCore(vc.ExtFrom, tmp, j, v, e)
+						}
+					}
+					// log.Debug("抽取-规则", tmp)
 
-			//抽取-规则
-			for _, v := range vc.RuleCores {
-				if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
-					ExtRegCore(vc.ExtFrom, tmp, j, v, e)
+					//抽取-后置规则
+					for _, v := range vc.RuleBacks {
+						if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
+							ExtRegBack(j, v, e.TaskInfo)
+						}
+					}
+					// log.Debug("抽取-后置规则", tmp)
 				}
 			}
-			// log.Debug("抽取-规则", tmp)
+		}else{
+			for _, vc1 := range e.RuleCores[j.Category+"_"+j.CategorySecond] {
+				for _, vc := range vc1 {
+					tmp := ju.DeepCopy(doc).(map[string]interface{})
+					//是否进入逻辑
+					if !ju.Logic(vc.LuaLogic, tmp) {
+						continue
+					}
+					//抽取-前置规则
+					for _, v := range vc.RulePres {
+						if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
+							tmp = ExtRegPre(tmp, j, v, e.TaskInfo)
+						}
+					}
+					// log.Debug("抽取-前置规则", tmp)
 
-			//抽取-后置规则
-			for _, v := range vc.RuleBacks {
-				if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
-					ExtRegBack(j, v, e.TaskInfo)
+					//抽取-规则
+					for _, v := range vc.RuleCores {
+						if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
+							ExtRegCore(vc.ExtFrom, tmp, j, v, e)
+						}
+					}
+					// log.Debug("抽取-规则", tmp)
+
+					//抽取-后置规则
+					for _, v := range vc.RuleBacks {
+						if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{
+							ExtRegBack(j, v, e.TaskInfo)
+						}
+					}
+					// log.Debug("抽取-后置规则", tmp)
 				}
 			}
-			// log.Debug("抽取-后置规则", tmp)
 		}
 
+
 		//全局后置规则
 		for _, v := range e.RuleBacks {
 			if value, ok := e.FileFields.Load(v.Field);ok && qu.IntAllDef(value,1) >0{

+ 206 - 146
src/jy/extract/extractInit.go

@@ -55,20 +55,22 @@ type TaskInfo struct {
 	TestLua                             bool      //检查测试用
 }
 type ExtractTask struct {
-	Id            string              //任务id
-	IsRun         bool                //是否启动
-	Content       string              //信息内容
-	TaskInfo      *TaskInfo           //任务信息
-	RulePres      []*RegLuaInfo       //通用前置规则
-	RuleBacks     []*RegLuaInfo       //通用后置规则
-	RuleCores     []*RuleCore         //抽取规则
-	PkgRuleCores  []*RuleCore         //分包抽取规则
-	Tag           map[string][]*Tag   //标签库
-	ClearFn       map[string][]string //清理函数
-	IsExtractCity bool                //是否开启城市抽取
-	Fields        map[string]int      //抽取属性组
-
-	IsFileField bool           //是否开启附件抽取
+	Id        string        //任务id
+	IsRun     bool          //是否启动
+	Content   string        //信息内容
+	TaskInfo  *TaskInfo     //任务信息
+	RulePres  []*RegLuaInfo //通用前置规则
+	RuleBacks []*RegLuaInfo //通用后置规则
+	RuleBlock *ju.RuleBlock
+	//RuleCores      []*RuleCore         //抽取规则
+	RuleCores     map[string]map[string][]*RuleCore //分类抽取规则
+	PkgRuleCores  []*RuleCore                       //分包抽取规则
+	Tag           map[string][]*Tag                 //标签库
+	ClearFn       map[string][]string               //清理函数
+	IsExtractCity bool                              //是否开启城市抽取
+	Fields        map[string]int                    //抽取属性组
+
+	IsFileField bool      //是否开启附件抽取
 	FileFields  *sync.Map //抽取附件属性组
 
 	ResultChanel chan bool                  //抽取结果详情
@@ -92,6 +94,8 @@ type ExtractTask struct {
 	AreaProvinceGet   *ju.DFA //省
 	AreaSimGet        *ju.DFA //市简称
 	AreaStreet        *ju.DFA //街道
+
+	InfoType []map[string]interface{}
 }
 
 type ClearTaskInfo struct {
@@ -263,156 +267,183 @@ func (e *ExtractTask) InitRuleBacks() {
 		}
 	}
 }
+func (e *ExtractTask) InfoTypeList() {
+	infolist1, _ := db.Mgo.Find("infotype", `{}`, `{}`, `{}`, false, -1, -1)
+	infolist := *infolist1
+	for _, v := range infolist {
+		e.InfoType = append(e.InfoType, v)
+	}
+}
 
 //加载抽取规则
 func (e *ExtractTask) InitRuleCore() {
 	defer qu.Catch()
 	e.Fields = map[string]int{}
-	e.RuleCores = []*RuleCore{}
-	vinfos, _ := db.Mgo.Find("versioninfo", `{"vid":"`+e.TaskInfo.VersionId+`","delete":false}`, nil, nil, false, -1, -1)
-	for _, vinfo := range *vinfos {
-		if b, _ := vinfo["isuse"].(bool); !b {
+	infolist, _ := db.Mgo.Find("infotype", `{}`, `{}`, `{}`, false, -1, -1)
+	e.RuleCores = make(map[string]map[string][]*RuleCore)
+	for _, v := range *infolist {
+		topclass := qu.ObjToString(v["topclass"])
+		if v["subclass"] == nil {
+			e.RuleCores[topclass] = make(map[string][]*RuleCore)
+			for attr, _ := range v["fields"].(map[string]interface{}) {
+				vinfo, _ := db.Mgo.FindOneByField("versioninfo", `{"vid":"`+e.TaskInfo.VersionId+`","delete":false,"s_field":"`+attr+`"}`, `{}`)
+				e.RuleCores[topclass][attr] = append(e.RuleCores[topclass][attr], e.InfoRole(*vinfo)...)
+			}
+		} else {
+			for ca, fs := range v["subclass"].(map[string]interface{}) {
+				e.RuleCores[topclass+"_"+ca] = make(map[string][]*RuleCore)
+				for field, _ := range fs.(map[string]interface{}) {
+					vinfo, _ := db.Mgo.FindOneByField("versioninfo", `{"vid":"`+e.TaskInfo.VersionId+`","delete":false,"s_field":"`+field+`"}`, `{}`)
+					e.RuleCores[topclass+"_"+ca][field] = append(e.RuleCores[topclass+"_"+ca][field], e.InfoRole(*vinfo)...)
+				}
+			}
+		}
+	}
+}
+func (e *ExtractTask) InfoRole(vinfo map[string]interface{}) []*RuleCore {
+	maps := []*RuleCore{}
+	if b, _ := vinfo["isuse"].(bool); !b {
+		return nil
+	}
+	s_field := qu.ObjToString(vinfo["s_field"])
+	pid := qu.BsonIdToSId(vinfo["_id"])
+	list, _ := db.Mgo.Find("rule_logic", `{"pid":"`+pid+`","delete":false}`, nil, nil, false, -1, -1)
+	for _, vv := range *list {
+		if b, _ := vv["isuse"].(bool); !b {
 			continue
 		}
-		s_field := qu.ObjToString(vinfo["s_field"])
-		pid := qu.BsonIdToSId(vinfo["_id"])
-		list, _ := db.Mgo.Find("rule_logic", `{"pid":"`+pid+`","delete":false}`, nil, nil, false, -1, -1)
-		for _, vv := range *list {
-			if b, _ := vv["isuse"].(bool); !b {
-				continue
+		rcore := &RuleCore{}
+		rcore.Field = s_field
+		rcore.LuaLogic = qu.ObjToString(vv["s_luascript"]) //是否进入逻辑脚本
+		rcore.ExtFrom = qu.If(vv["extfrom"].(bool), "title", "detail").(string)
+		//前置规则
+		rulePres := []*RegLuaInfo{}
+		plist, _ := db.Mgo.Find("rule_logicpre", `{"sid":"`+qu.BsonIdToSId(vv["_id"])+`","delete":false}`, nil, nil, false, -1, -1)
+		for _, v := range *plist {
+			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)
-			//前置规则
-			rulePres := []*RegLuaInfo{}
-			plist, _ := db.Mgo.Find("rule_logicpre", `{"sid":"`+qu.BsonIdToSId(vv["_id"])+`","delete":false}`, nil, nil, false, -1, -1)
-			for _, v := range *plist {
-				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)
+				rulePres = append(rulePres, 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") {
+						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: ""}
+					}
 					rulePres = append(rulePres, 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") {
-							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: ""}
-						}
-						rulePres = append(rulePres, rinfo)
-					}, func(err interface{}) {
-						log.Debug(rinfo.Code, rinfo.Field, err)
-					})
-				}
+				}, func(err interface{}) {
+					log.Debug(rinfo.Code, rinfo.Field, err)
+				})
 			}
-			rcore.RulePres = rulePres
+		}
+		rcore.RulePres = rulePres
 
-			//后置规则
-			ruleBacks := []*RegLuaInfo{}
-			blist, _ := db.Mgo.Find("rule_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)
+		//后置规则
+		ruleBacks := []*RegLuaInfo{}
+		blist, _ := db.Mgo.Find("rule_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)
+				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") {
+						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") {
-							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)
-					}, func(err interface{}) {
-						log.Debug(rinfo.Code, rinfo.Field, err)
-					})
-				}
+				}, func(err interface{}) {
+					log.Debug(rinfo.Code, rinfo.Field, err)
+				})
 			}
-			rcore.RuleBacks = ruleBacks
+		}
+		rcore.RuleBacks = ruleBacks
 
-			//抽取规则
-			ruleCores := []*RegLuaInfo{}
-			clist, _ := db.Mgo.Find("rule_logicore", `{"sid":"`+qu.BsonIdToSId(vv["_id"])+`","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)
-					//提取全部属性
-					rinfo.LFields = getALLFields()
-					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") {
-							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])
-								}
+		//抽取规则
+		ruleCores := []*RegLuaInfo{}
+		clist, _ := db.Mgo.Find("rule_logicore", `{"sid":"`+qu.BsonIdToSId(vv["_id"])+`","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)
+				//提取全部属性
+				rinfo.LFields = getALLFields()
+				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") {
+						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])
 							}
-							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)
-					})
-				}
+						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.RuleCores = ruleCores
-			//
-			e.RuleCores = append(e.RuleCores, rcore)
 		}
+		rcore.RuleCores = ruleCores
+		//
+		maps = append(maps, rcore)
 	}
+	return maps
 }
 
 //加载分包抽取规则
@@ -927,7 +958,7 @@ func (e *ExtractTask) InitFile() {
 
 	if (*ve)["s_filefileds"] != nil {
 		for _, vff := range (*ve)["s_filefileds"].([]interface{}) {
-			syscefiled.Store(vff.(string),1)
+			syscefiled.Store(vff.(string), 1)
 		}
 	}
 	e.FileFields = syscefiled
@@ -981,3 +1012,32 @@ func (c *ClearTask) InitClearLuas() {
 		}
 	}
 }
+
+//加载分块规则
+func (e *ExtractTask) InitBlockRule() {
+	datas, _ := db.Mgo.Find("block_info", map[string]interface{}{
+		"vid":    e.TaskInfo.VersionId,
+		"delete": false,
+	}, `{"index":-1}`, `{"block_reg":1,"title_reg":1}`, false, -1, -1)
+	brs, trs := []*regexp.Regexp{}, []*regexp.Regexp{}
+	for _, v := range *datas {
+		block_reg, _ := v["block_reg"].(string)
+		block_reg, _ = strconv.Unquote(`"` + block_reg + `"`)
+		title_reg, _ := v["title_reg"].(string)
+		title_reg, _ = strconv.Unquote(`"` + title_reg + `"`)
+		if block_reg == "" || title_reg == "" {
+			continue
+		}
+		b_reg, b_err := regexp.Compile(block_reg)
+		t_reg, t_err := regexp.Compile(title_reg)
+		if b_err != nil || t_err != nil {
+			continue
+		}
+		brs = append(brs, b_reg)
+		trs = append(trs, t_reg)
+	}
+	e.RuleBlock = &ju.RuleBlock{
+		BlockRegs: brs,
+		TitleRegs: trs,
+	}
+}

+ 7 - 6
src/jy/extract/extractudp.go

@@ -103,6 +103,7 @@ func ExtractByUdp(sid, eid string, instanceId ...string) {
 		ext.InitRulePres()
 		ext.InitRuleBacks()
 		ext.InitRuleCore()
+		ext.InitBlockRule()
 		ext.InitTag()
 		ext.InitClearFn()
 		if ext.IsExtractCity { //版本上控制是否开始城市抽取
@@ -159,9 +160,9 @@ func ExtractByUdp(sid, eid string, instanceId ...string) {
 					var j, jf *ju.Job
 					if ext.IsFileField && v["projectinfo"] != nil {
 						v["isextFile"] = true
-						j, jf = PreInfo(v)
+						j, jf = ext.PreInfo(v)
 					} else {
-						j, _ = PreInfo(v)
+						j, _ = ext.PreInfo(v)
 					}
 					ext.TaskInfo.ProcessPool <- true
 					go ext.ExtractProcess(j, jf)
@@ -185,9 +186,9 @@ func ExtractByUdp(sid, eid string, instanceId ...string) {
 					var j, jf *ju.Job
 					if ext.IsFileField && v["projectinfo"] != nil {
 						v["isextFile"] = true
-						j, jf = PreInfo(v)
+						j, jf = ext.PreInfo(v)
 					} else {
-						j, _ = PreInfo(v)
+						j, _ = ext.PreInfo(v)
 					}
 					ext.TaskInfo.ProcessPool <- true
 					go ext.ExtractProcess(j, jf)
@@ -225,9 +226,9 @@ func ExtractByUdp(sid, eid string, instanceId ...string) {
 				var j, jf *ju.Job
 				if ext.IsFileField && v["projectinfo"] != nil {
 					v["isextFile"] = true
-					j, jf = PreInfo(v)
+					j, jf = ext.PreInfo(v)
 				} else {
-					j, _ = PreInfo(v)
+					j, _ = ext.PreInfo(v)
 				}
 				ext.TaskInfo.ProcessPool <- true
 				wg.Add(1)

+ 7 - 7
src/jy/pretreated/analystep.go

@@ -21,20 +21,20 @@ func AnalyStart(job *util.Job) {
 	//
 	tabs, ration := ComputeConRatio(con, 1)
 	if len(tabs) > 0 {
-		newcon, newtabs, newration := findBigText(con, ration, tabs)
+		newcon, newtabs, newration := FindBigText(con, ration, tabs)
 		if newcon != "" && newration == 0 {
 			con = newcon
 			tabs = newtabs
 			ration = newration
 		}
 	}
-	blockArrays, _ := DivideBlock(con, 1)
+	blockArrays, _ := DivideBlock(con, 1, job.RuleBlock)
 	if len(blockArrays) > 0 { //有分块
 		//从块里面找分包
 		job.BlockPackage = FindPackageFromBlocks(&blockArrays, job.Title)
 		for _, bl := range blockArrays {
 			if len([]rune(bl.Text)) > 80 {
-				ba1, _ := DivideBlock(bl.Text, 1)
+				ba1, _ := DivideBlock(bl.Text, 1, job.RuleBlock)
 				if len(ba1) > 0 {
 					t := ""
 					for _, t1 := range ba1 {
@@ -49,7 +49,7 @@ func AnalyStart(job *util.Job) {
 			t1, _ := ComputeConRatio(bl.Text, 2)
 			if len(t1) > 0 {
 				job.HasTable = 1 //添加标识:文本中有table
-				tabres := AnalyTableV2(t1, job.Category, bl.Title, bl.Text, 2, job.SourceMid)
+				tabres := AnalyTableV2(t1, job.Category, bl.Title, bl.Text, 2, job.SourceMid, job.RuleBlock)
 				processTableResult(tabres, bl, job)
 				if bl.Title == "" && tabres.BlockTag != "" {
 					bl.Title = tabres.BlockTag
@@ -67,7 +67,7 @@ func AnalyStart(job *util.Job) {
 			job.HasTable = 1 //添加标识:文本中有table
 			newCon = TextAfterRemoveTable(con)
 			job.BlockPackage = FindPackageFromText(job.Title, newCon)
-			tabres := AnalyTableV2(tabs, job.Category, "", con, 1, job.SourceMid)
+			tabres := AnalyTableV2(tabs, job.Category, "", con, 1, job.SourceMid, job.RuleBlock)
 			processTableResult(tabres, bl, job)
 			//			for k, v := range bl.TableKV.Kv {
 			//				log.Println("bl.TableKV.Kv", k, v)
@@ -224,7 +224,7 @@ func processTableResult(tabres *TableResult, block *util.Block, job *util.Job) {
 //ration==1 遍历所有tabs,ration!=1 tabs只有一个
 func tableDivideBlock(con string, ration float32, tabs []*goquery.Selection) string {
 	if len(tabs) != 1 {
-		return ""
+		//return ""
 	}
 	for _, tab := range tabs {
 		content := ""
@@ -275,7 +275,7 @@ func tableDivideBlock(con string, ration float32, tabs []*goquery.Selection) str
 }
 
 //查找大文本,5次
-func findBigText(con string, r float32, t []*goquery.Selection) (content string, tabs []*goquery.Selection, ration float32) {
+func FindBigText(con string, r float32, t []*goquery.Selection) (content string, tabs []*goquery.Selection, ration float32) {
 	content = tableDivideBlock(con, r, t)
 	if content == "" {
 		return

+ 11 - 6
src/jy/pretreated/analytable.go

@@ -524,7 +524,7 @@ func (table *Table) MergerToTableresult() {
 解析表格入口
 返回:汇总表格对象
 **/
-func AnalyTableV2(tabs []*goquery.Selection, toptype, blockTag, con string, itype int, _id interface{}) (tabres *TableResult) {
+func AnalyTableV2(tabs []*goquery.Selection, toptype, blockTag, con string, itype int, _id interface{}, ruleBlock *u.RuleBlock) (tabres *TableResult) {
 	defer qutil.Catch()
 	//u.Debug(con)
 	if itype == 1 {
@@ -532,7 +532,7 @@ func AnalyTableV2(tabs []*goquery.Selection, toptype, blockTag, con string, ityp
 		con = RepairCon(con)
 	}
 	//生成tableresult对象
-	tabres = NewTableResult(_id, toptype, blockTag, con, itype)
+	tabres = NewTableResult(_id, toptype, blockTag, con, itype, ruleBlock)
 	//可以有多个table
 	for _, table := range tabs {
 		//隐藏表格跳过
@@ -1866,7 +1866,7 @@ func (tn *Table) CheckMultiPackageByTable() (b bool, index []string) {
 				L:
 					for in2, v1 := range vs {
 						if len([]rune(v1)) < 20 && !moneyNum.MatchString(v1) && FindVal2_1.MatchString(v1) {
-							for _, serial := range regSerialTitles_2 {
+							for _, serial := range tn.TableResult.RuleBlock.TitleRegs {
 								if serial.MatchString(v1) {
 									break L
 								}
@@ -2019,8 +2019,13 @@ func (tn *Table) CheckMultiPackageByTable() (b bool, index []string) {
 					//删除子包的kv
 					//u.Debug("----==1==-------", k1)
 					k1tags := u.GetTags(k1)
-					if !(len(k1tags) > 0 && k1tags[0].Value == "采购单位") {
-						tn.SortKV.RemoveKey(k1)
+					//if !(len(k1tags) > 0 && k1tags[0].Value == "采购单位") {
+					//	tn.SortKV.RemoveKey(k1)
+					//}
+					for _,vcgdw:=range k1tags{
+						if vcgdw.Value =="采购单位"{
+							tn.SortKV.RemoveKey(k1)
+						}
 					}
 				} else if val, bvs := v1.(string); bvs && len(index) == 1 {
 					//删除子包的kv
@@ -2394,7 +2399,7 @@ L:
 				jumpNextTd = false
 			}
 			///////////////////////////////////////
-			thisTdKvs := kvAfterDivideBlock(td.Text, 3)
+			thisTdKvs := kvAfterDivideBlock(td.Text, 3, tn.TableResult.RuleBlock)
 			if len(thisTdKvs) == 0 {
 				thisTdKvs = colonkvEntity.GetKvs(td.Text, "", 2)
 			}

+ 11 - 11
src/jy/pretreated/division.go

@@ -11,15 +11,15 @@ import (
 
 //分块、分段功能
 var (
-	regSerialTitles = []string{
+	/*regSerialTitles = []string{
 		"([一二三四五六七八九十]+)[\u3000\u2003\u00a0\\s]*[、..::,](.*)",
 		"[((]([一二三四五六七八九十]+)[))][\u3000\u2003\u00a0\\s]*[、..::]?(.*)",
 		"(\\d+)[\u3000\u2003\u00a0\\s]*、(.*)",
 		"(\\d+)[\u3000\u2003\u00a0\\s]*[..]([^\\d][^\r\n]+)",
 		"(\\d+)[\u3000\u2003\u00a0\\s]+([^\\d][^\r\n]+)",
 		"1[..](\\d+)[\u3000\u2003\u00a0\\s]+([^\\d..][^\r\n]+)",
-	}
-	regSerialTitles_1 = []*regexp.Regexp{
+	}*/
+	/*regSerialTitles_1 = []*regexp.Regexp{
 		regexp.MustCompile("([\r\n][\u3000\u2003\u00a0\\s]*|^[\u3000\u2003\u00a0\\s]*)([一二三四五六七八九十]+)[\u3000\u2003\u00a0\\s]*[、..::,](.*)"),
 		regexp.MustCompile("([\r\n][\u3000\u2003\u00a0\\s]*|^[\u3000\u2003\u00a0\\s]*)[((]([一二三四五六七八九十]+)[))][\u3000\u2003\u00a0\\s]*[、..::]?(.*)"),
 		regexp.MustCompile("([\r\n][\u3000\u2003\u00a0\\s]*|^[\u3000\u2003\u00a0\\s]*)(\\d+)[\u3000\u2003\u00a0\\s]*、(.*)"),
@@ -36,7 +36,7 @@ var (
 		regexp.MustCompile("^(\\d+)[\u3000\u2003\u00a0\\s]+([^\\d][^\r\n]+)$"),
 		regexp.MustCompile("^1[..](\\d+)[\u3000\u2003\u00a0\\s]+([^\\d..][^\r\n]+)$"),
 		regexp.MustCompile("^[(](\\d+)[\u3000\u2003\u00a0\\s)]+([^\r\n]+)$"),
-	}
+	}*/
 	regReplAllTd       = regexp.MustCompile("(?smi)<td.*?>.+?</td>")
 	regIsNumber        = regexp.MustCompile("^\\d+$")
 	regIsChineseNumber = regexp.MustCompile("^[一二三四五六七八九十]+$")
@@ -64,7 +64,7 @@ var (
 )
 
 //分块
-func DivideBlock(content string, from int) ([]*util.Block, int) {
+func DivideBlock(content string, from int, ruleBlock *util.RuleBlock) ([]*util.Block, int) {
 	defer qutil.Catch()
 	returnValue := 0
 	var blocks []*util.Block
@@ -75,7 +75,7 @@ func DivideBlock(content string, from int) ([]*util.Block, int) {
 	//contentTemp := regReplAllTd.ReplaceAllString(content, "")
 	contentTemp := TextAfterRemoveTable(content)
 	tdIndexs := regReplAllTd.FindAllStringSubmatchIndex(content, -1)
-	regContenSerialTitle, regSerialTitleIndex := getSerialType(contentTemp)
+	regContenSerialTitle, regSerialTitleIndex := getSerialType(contentTemp, ruleBlock.BlockRegs)
 	//没有分块
 	if regSerialTitleIndex == -1 {
 		if len(contentTemp) == len(content) {
@@ -86,7 +86,7 @@ func DivideBlock(content string, from int) ([]*util.Block, int) {
 		}
 	}
 	//匹配序号和标题
-	regSerialTitle := regSerialTitles_2[regSerialTitleIndex]
+	regSerialTitle := ruleBlock.TitleRegs[regSerialTitleIndex]
 	indexs := regContenSerialTitle.FindAllStringIndex(content, -1)
 	indexs = filterSerial(content, indexs, tdIndexs)
 	//头块
@@ -330,11 +330,11 @@ func filterSerial(content string, indexs, tdIndexs [][]int) [][]int {
 }
 
 //获取正文所用的序号类型
-func getSerialType(content string) (*regexp.Regexp, int) {
+func getSerialType(content string, blockRegs []*regexp.Regexp) (*regexp.Regexp, int) {
 	var regContenSerialTitle *regexp.Regexp
 	//先判断文章最外层使用的是哪种序号
 	contentStartIndex, regSerialTitleIndex := -1, -1
-	for k, v := range regSerialTitles_1 {
+	for k, v := range blockRegs {
 		indexs := v.FindStringIndex(content)
 		//只用最外层的序号,里面的过滤掉
 		if len(indexs) == 2 && !regSpliteSegment.MatchString(strings.TrimSpace(content[indexs[0]:indexs[1]])) && (contentStartIndex == -1 || indexs[0] < contentStartIndex) {
@@ -753,8 +753,8 @@ func interceptText(indexs []int, indexPkgMap map[int]string, pkgIndexMap map[str
 }
 
 //分块之后的kv
-func kvAfterDivideBlock(text string, from int) []*util.Kv {
-	blocks, _ := DivideBlock(text, from)
+func kvAfterDivideBlock(text string, from int, ruleBlock *util.RuleBlock) []*util.Kv {
+	blocks, _ := DivideBlock(text, from, ruleBlock)
 	kvs := []*util.Kv{}
 	for _, v := range blocks {
 		//util.Debug(v.Text)

+ 5 - 3
src/jy/pretreated/tablev2.go

@@ -33,10 +33,11 @@ type TableResult struct {
 	HasKey         int                   //有key
 	HasBrand       int                   //有品牌
 	HasGoods       int                   //有商品
+	RuleBlock      *u.RuleBlock
 }
 
 //快速创建TableResult对象
-func NewTableResult(Id interface{}, Toptype, BlockTag, con string, Itype int) *TableResult {
+func NewTableResult(Id interface{}, Toptype, BlockTag, con string, Itype int, ruleBlock *u.RuleBlock) *TableResult {
 	return &TableResult{
 		Id:           Id,
 		Toptype:      Toptype,
@@ -48,6 +49,7 @@ func NewTableResult(Id interface{}, Toptype, BlockTag, con string, Itype int) *T
 		PackageMap:   NewSortMap(),
 		SortKV:       NewSortMap(),
 		SortKVWeight: map[string]int{},
+		RuleBlock:    ruleBlock,
 	}
 }
 
@@ -144,7 +146,7 @@ func NewTD(Goquery *goquery.Selection, tr *TR, table *Table) *TD {
 					stag = str
 				}
 			}
-			sonts := AnalyTableV2(tabs, ts.Toptype, stag, td.Html, 2, ts.Id)
+			sonts := AnalyTableV2(tabs, ts.Toptype, stag, td.Html, 2, ts.Id, table.TableResult.RuleBlock)
 			td.BH = false
 
 			td.SonTableResult = sonts
@@ -212,7 +214,7 @@ func NewTD(Goquery *goquery.Selection, tr *TR, table *Table) *TD {
 	ub := []*u.Block{}
 	if lentxt > 50 { //看是否划块
 		//u.Debug(txt)
-		ub, _ = DivideBlock(txt, 2)
+		ub, _ = DivideBlock(txt, 2, nil)
 		if len(ub) > 0 {
 			colonKvWeight := map[string]int{}
 			spaceKvWeight := map[string]int{}

+ 18 - 7
src/jy/util/article.go

@@ -1,9 +1,14 @@
 package util
 
+import (
+	"regexp"
+)
+
 //
 type Job struct {
 	SourceMid    string                            //数据源的MongoId
 	Category     string                            //类别
+	CategorySecond string							//二级分类
 	Content      string                            //正文
 	Title        string                            //标题
 	SpiderCode   string                            //爬虫代码
@@ -18,13 +23,13 @@ type Job struct {
 	BlockPackage map[string]*BlockPackage          //块中的分包
 	Winnerorder  []map[string]interface{}          //中标候选人排序
 	PackageInfo  map[string]map[string]interface{} //分包信息
-
-	BrandData [][]map[string]string //
-	HasTable  int                   //有table
-	HasKey    int                   //是否匹配到table中的标题
-	HasBrand  int                   //有品牌
-	HasGoods  int                   //有商品
-	IsFile    bool                  //有附件
+	RuleBlock    *RuleBlock                        //分块规则
+	BrandData    [][]map[string]string             //
+	HasTable     int                               //有table
+	HasKey       int                               //是否匹配到table中的标题
+	HasBrand     int                               //有品牌
+	HasGoods     int                               //有商品
+	IsFile       bool                              //有附件
 }
 
 type ExtField struct {
@@ -38,6 +43,12 @@ type ExtField struct {
 	Score     int         //得分
 }
 
+//分块规则
+type RuleBlock struct {
+	BlockRegs []*regexp.Regexp
+	TitleRegs []*regexp.Regexp
+}
+
 //块
 type Block struct {
 	Tags     []Tags          //对块做的标签,可以作为数据抽取的依据

+ 1 - 0
src/main.go

@@ -31,6 +31,7 @@ func init() {
 	//初始化redis
 	redis.InitRedisBySize(qu.ObjToString(util.Config["redis"]), 50, 30, 240)
 	//初始化elastic连接
+	//"winner=172.17.145.179:2710,buyer=172.17.145.179:2711"
 	elastic.InitElasticSize(qu.ObjToString(util.Config["elasticsearch"]), qu.IntAllDef(util.Config["elasticPoolSize"], 30))
 }
 

+ 3 - 3
src/main_test.go

@@ -28,8 +28,8 @@ func Test_han(t *testing.T) {
 }
 func Test_task(t *testing.T) {
 	Mgo = MgoFactory(1, 3, 120, "192.168.3.207:27082", "extract_kf")
-	//extract.StartExtractTaskId("5b8f804025e29a290415aee1")
-	extract.StartExtractTestTask("5c528686698414055c47b115", "5a524c3d40d2d9bbe8e9cef0", "1", "mxs_v2", "mxs_v2")
+	//extract.StartExtractTaskId("5b8f804025e29a290415aee1")5c528686698414055c47b115
+	extract.StartExtractTestTask("5b8f804025e29a290415aee1", "5a53966e40d2d9bbe8f7d30a", "1", "mxs_v2", "mxs_v2")
 	//extract.StartExtractTestTask("5c3d75c96984142998eb00e1", "5c2a3d28a5cb26b9b76144dd", "100", "mxs_v3", "mxs_v3")
 	time.Sleep(5 * time.Second)
 }
@@ -47,7 +47,7 @@ func Test_reg(t *testing.T) {
 	log.Println(tmp)
 }
 
-func Test_reg(t *testing.T) {
+func Test_reg1(t *testing.T) {
 	context := `sss<input  name="AgentCode" size="30" maxsize="50" value="91370800688271668P" class="textbox">
     dfdf<input type="hidden" name="AgentCode" size="30" maxsize="50" value="tttt" class="textbox"></input>`
 	reg := regexp.MustCompile(`<\s*input.*value=['"](.[^'"]+).+>`)

+ 29 - 58
src/web/templates/admin/audit_auditone.html

@@ -29,8 +29,12 @@
 		            <table id="dataauditTable" class="table table-bordered table-hover">
 		              <thead>
 		              <tr>
-		                <th>名称</th>
-						<th>是否审核</th>
+		                <th>字段名称</th>
+						<th>字段值</th>
+						<th>ExtractID</th>
+						<th>结果表</th>
+						<th>分包</th>
+						<th>时间</th>
 						<th>操作</th>
 		              </tr>
 		              </thead>
@@ -87,13 +91,11 @@
 <script>
 menuActive("recogfield")
 var id = "";
+var eid = "";
 var classifymap = {};
 var bid = 1;
+var coll = "";
 var field = {{.name}}
-var s_coll =sessionStorage.getItem("s_coll");
-if(s_coll == null){
-	s_coll = "";
-}
 $(function () {
 	ttable=$('#dataauditTable').DataTable({
 		"paging"      : true,
@@ -104,58 +106,33 @@ $(function () {
 		"autoWidth"   : false,
 		"serverSide"  : true,
 		"ajax": {
-			"url": "/admin/audit/auditone",
+			"url": "/admin/audit/auditonefield",
 			"type": "post",
-			"data": {"name":{{.name}},"s_coll":s_coll}
+			"data": {"field":{{.name}}}
 		},
 		"language": {
             "url": "/res/dist/js/dataTables.chinese.lang"
         },
 		"columns": [
-            { "data": "name"},
-			{ "data": "_id",render:function(val,a,row){
-				return "否";
+            { "data": "field"},
+			{ "data": "val"},
+			{ "data": "extractid"},
+			{ "data": "extractcoll"},
+			{ "data": "ispackage",render:function(val,a,row){
+				if(val){
+					return "是"
+				}else{
+					return "否"
+				}
 			}},
+			{ "data": "l_createtime"},
 			{ "data": "_id",render:function(val,a,row){
-					return '<a class="btn btn-sm btn-success" href="#" onclick="audit(\''+row.name+'\',\''+val+'\')">审核</a>'
+					return '<a class="btn btn-sm btn-success" href="#" onclick="audit(\''+row.val+'\',\''+val+'\',\''+row.extractid+'\',\''+row.extractcoll+'\')">审核</a>'
 			}}
-       	],
-		"fnServerParams": function (e) {  
-			var source=$("#datasource").val();
-			if(source){
-				e.source = source;
-			}else{
-				e.source = "-1";
-			}
-			
-		}
-	});
-	ttable.on('init.dt', function () {
-		//结果表
-		var result ="<div class='form-group'><label for='name'>结果表:</label>"+
-			"<input id='resultcoll' class='form-control input-sm' value=\'"+s_coll+"\' placeholder='请输入要查询的表...'></input>&nbsp;&nbsp;"+
-			"<button class='btn btn-primary' onclick='search()'>查询</button><div>";
-		$("#dataauditTable_filter").prepend("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
-		$("#dataauditTable_filter").prepend(result);
-		//内外层数据
-		var opt="<option value='-1'>外层</option>"+
-				"<option value='1'>内层</option>";
-		var select="<div class='form-group'><label for='name'>数据来源:</label>"+
-			"<select id='datasource' onchange='checkclick(this.value)' class='form-control input-sm'>"+
-			opt+
-			"</select></div>"
-		$("#dataauditTable_filter").prepend("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
-		$("#dataauditTable_filter").prepend(select);
-		//样式
-		
-		$("#dataauditTable_wrapper .col-sm-6").css({width:"100%"});
+       	]
 	});
 })
 
-function checkclick(urgency){
-	ttable.ajax.reload();
-}
-
 function addaudit(){
 	//查询分类数据
 	bid = 1;
@@ -226,24 +203,25 @@ function addsave(auditname,parentclass,childclass){
 }
 
 //审核
-function audit(name,_id){
+function audit(val,_id,extractid,extractcoll){
 	bid = 2;
 	getbuyerclass();
 	id = _id;
-	$("#auditname").val(name);
+	eid = extractid;
+	coll = extractcoll;
+	$("#auditname").val(val);
 	$("#audittitleinfo").html("审核");
 	$("#modal-info-auditdata").modal("show");
 }
 //审核确认
 function auditsave(parentclass,childclass){
-	var name = $("#auditname").val();
+	var val = $("#auditname").val();
 	$("#modal-info-auditdata").modal("hide");
-	var coll = sessionStorage.getItem("s_coll");
 	showConfirm("确定通过?", function() {
 		$.ajax({
 			url:"/admin/audit/auditsave",
 			type:"post",
-			data:{"coll":coll,"field":field,"name":name,"parentclass":parentclass,"childclass":childclass,"id":id},
+			data:{"field":field,"val":val,"parentclass":parentclass,"childclass":childclass,"id":id,"eid":eid,"coll":coll},
 			success:function(r){
 				if(r.rep){				
 					ttable.ajax.reload();
@@ -269,11 +247,4 @@ $(document).ready(function(){
 		}
 	});
 });
-
-//查询
-function search(){
-	var coll=$("#resultcoll").val();
-	sessionStorage.setItem("s_coll",coll);
-	window.location.href="/admin/audit/dataaudit?name="+{{.name}}+"&s_coll="+coll;
-}
 </script>

+ 190 - 0
src/web/templates/admin/blockinfo.html

@@ -0,0 +1,190 @@
+{{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/blockinfo?vid={{.vid}}">分块配置</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-striped table-bordered table-hover">
+		              <thead>
+		              <tr>
+						<th>优先级</th>
+						<th>分块正则</th>
+						<th>块标题正则</th>
+						<th>操作</th>
+		              </tr>
+		              </thead>
+		            </table>
+					<p class="text-danger text-right">注:可拖拽调整优先级顺序</p>
+		        </div>
+	          <!-- /.box-body -->
+	        </div>
+        <!-- /.box -->
+		</div>
+	</div>
+  </section>
+</div>
+	
+<!-- footer -->
+{{template "dialog"}}
+{{template "footer"}}
+<link rel="stylesheet" href="https://cdn.datatables.net/rowreorder/1.2.5/css/rowReorder.bootstrap.min.css">
+<script src="https://cdn.datatables.net/rowreorder/1.2.5/js/dataTables.rowReorder.min.js"></script>
+<script>
+menuActive("version")
+$(function () {
+	ttable=$('#dataTable').DataTable({
+		"columnDefs": [
+			{
+				"targets": 0,
+				visible:true
+			},
+	        {
+	            "orderable": false,
+	            "targets": "_all"
+	        }
+		],
+		rowReorder: {
+			dataSrc: 'index',
+            selector: 'tr'
+        },
+		"order": [[ 0, 'desc' ]],
+		"paging"      : false,
+		"lengthChange": false,
+		"searching"   : false,
+		"info"        : true,
+		"autoWidth"   : false,
+		"language": {
+            "url": "/res/dist/js/dataTables.chinese.lang"
+        },
+		"ajax": {
+			"url": "/admin/version/blockinfo_list",
+			"type": "post",
+			"data":{"vid":{{ .vid}}}
+		},
+		"columns": [
+			{"data": "index","orderable": false},
+			{"data": "block_reg","width":"50%"},
+			{"data": "title_reg","width":"30%"},
+			{"data":"_id","width":"12%",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>';
+			}}
+       	]
+	});
+	ttable.on('init.dt', function () {
+		$(".opr").click(function(){
+			var n=$(this).attr("opr")
+			var _tit="",htmlObj={},obj,tag=[]
+			switch(n){
+			case "edit":	
+                obj=ttable.row($(this).closest("tr")).data();
+			case "new":
+                tag=[
+						{label:"分块正则",s_label:"block_reg",type:"tpl_input",placeholder:"分块正则",must:true},
+						{label:"块标题正则",s_label:"title_reg",type:"tpl_input",placeholder:"块标题正则",must:true},
+                        {s_label:"_id",type:"tpl_hidden"},
+					]
+				
+				if(n=="new"){
+					_tit="新增规则"
+					obj={}
+				}else{
+					_tit="编辑规则"
+				}
+				htmlObj={
+					title:_tit,
+					tag:tag,
+					bts:[
+						{label:"保存",class:"btn-primary",
+							fun:function(){
+								var block_reg = $.trim($("#block_reg").val());
+								var title_reg = $.trim($("#title_reg").val());
+								var bcon=true;
+								if(block_reg==""||title_reg==""){
+									bcon=false;
+								}
+								if (bcon){
+									var obj={
+										_id:$("#_id").val(),
+										block_reg:block_reg,
+										title_reg:title_reg,
+										vid:{{.vid}}
+									}
+                                    //console.log(obj)							
+									$.post("/admin/version/blockinfo_save",obj,function(data){
+										if(data.status){
+											window.location.href="/admin/version/blockinfo?vid={{.vid}}";	
+										}else{
+											showTip("保存失败!",1000)
+										}
+									},'json')
+								}else{
+									alert("红色标签的表单不能为空!")
+								}
+							}
+						}
+					]
+				}
+			OpenDialog(htmlObj,obj)
+			break;
+			}
+		});
+	});
+	ttable.on( 'order.dt search.dt', function () {
+        ttable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
+            cell.innerHTML = i+1;
+        } );
+    } ).draw();
+	ttable.on( 'row-reordered', function ( e, diff, edit ) {
+		var _ids = [],indexs=[];
+		for(var i=0;i<diff.length;i++){
+			var rowData = ttable.row( diff[i].node ).data();
+			_ids.push(rowData._id);
+			indexs.push(rowData.index);
+		}
+		ttable.rowReorder.disable();
+		$.ajax({
+			type: "POST",
+			url: "/admin/version/blockinfo_updateindex",
+			data: {_ids:_ids,indexs:indexs},
+			dataType: "json",
+			traditional: true,
+			success: function(r){
+				ttable.rowReorder.enable();
+			}
+		});
+    });
+})
+function del(_id){
+	showConfirm("确定删除?", function() {
+		$.ajax({
+			url:"/admin/version/blockinfo_delete",
+			type:"post",
+			data:{"_id":_id},
+			success:function(r){
+				if(r.status){				
+					ttable.ajax.reload();
+				}else{
+					showTip("删除失败", 1000, function() {});
+				}
+			}
+		})
+	});
+}
+</script>

+ 302 - 0
src/web/templates/admin/class.html

@@ -0,0 +1,302 @@
+{{template "inc"}}
+<!-- Main Header -->
+{{template "header"}}
+<!-- Left side column. 权限菜单 -->
+{{template "memu"}}
+<head>
+    <style>
+
+        #selectclear2 select {
+            width:190px;
+            height:167px;
+            padding:5px;
+        }
+        #selectclear2{
+            display: flex;
+            flex-direction: row;
+        }
+        #selectclear2 .move{
+            display: flex;
+            flex-direction: column;
+            margin: 20px 25px
+        }
+        #selectclear2 .move button{
+            margin: 1px 0px;
+            padding: 4px 6px;
+        }
+        #selectclear2 .doublebox {
+            text-align:center;
+        }
+
+
+    </style>
+</head>
+
+<!-- Content Wrapper. Contains page content -->
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1>
+            <small><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-info" onclick="formReset()">新增分类抽取</button></small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="/admin/infotype"><i class="fa fa-dashboard"></i> 分类抽取</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>
+                            </tr>
+                            </thead>
+                        </table>
+                    </div>
+                    <!-- /.box-body -->
+                </div>
+                <!-- /.box -->
+            </div>
+        </div>
+    </section>
+</div>
+
+<div class="modal fade" id="modal-info">
+    <div class="modal-dialog">
+        <form id="userform" class="form-horizontal" role="form">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title">分类信息</h4>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label" style="width:20% !important;">一级分类名称:</label>
+                        <div class="col-sm-10" style="width:80% !important;">
+                            <select id="topclass" name="topclass" class="form-control" onclick="topfunc()">
+                            </select>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label" style="width:20% !important;">二级分类名称:</label>
+                        <div class="col-sm-10" style="width:80% !important;">
+                            <select id="subclass" name="subclass" class="form-control" >
+                            </select>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label" style="width:20% !important;">属性:</label>
+                        <div class="col-sm-10" id="selectclear2" style="width:75% !important;">
+                            <div class="doublebox">
+                                <select multiple="multiple" id="select3" style="overflow-x: scroll;"></select>
+                            </div>
+                            <div class="move" style="margin: 10px;">
+                                <button type="button" id="up2" class="btn btn-primary">上移</button>
+                                <button type="button" id="right2" class="btn btn-primary">右移</button>
+                                <button type="button" id="left2" class="btn btn-primary">左移</button>
+                                <button type="button" id="down2" class="btn btn-primary">下移</button>
+                            </div>
+                            <div class="doublebox">
+                                <select multiple="multiple" id="select4" style="overflow-x: scroll;"></select>
+                            </div>
+                        </div>
+                    </div>
+                    <!--<div class="form-group">
+                        <label for="modify" class="col-sm-2 control-label">二级菜单:</label>
+                        <div id="secondmenu" class="col-sm-10">
+                            <input type="button" value="+" onclick="append()"></input>
+                        </div>
+                    </div>-->
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal" onclick="formReset()">取消</button>
+                    <button type="button" class="btn btn-primary" onclick="save()">保存</button>
+                </div>
+            </div>
+            <!-- /.modal-content -->
+        </form>
+        <input type="hidden" id="_id">
+    </div>
+    <!-- /.modal-dialog -->
+</div>
+<!-- /.modal -->
+
+<!-- footer -->
+{{template "footer"}}
+
+<script>
+    menuActive("infotype")
+    $(function () {
+        ttable=$('#dataTable').DataTable({
+            "paging"      : true,
+            "lengthChange": false,
+            "searching"   : true,
+            "ordering"    : true,
+            "info"        : true,
+            "autoWidth"   : false,
+            "ajax": {
+                "url": "/admin/infotype/data",
+                "type": "post",
+                "data":{}
+            },
+            "language": {
+                "url": "/res/dist/js/dataTables.chinese.lang"
+            },
+            "columns": [
+                { "data": "topclass",render:function(val,a,row){
+                        return row.topclass}},
+                { "data": "subclass",render:function(val,a,row){
+                        return row.subclass}},
+                {"data":"_id",render:function(val,a,row){
+                        return "<a href='#' onclick='edit(\""+val+"\",\""+row.subclass+"\")'><i class='fa fa-fw fa-edit text-yellow'></i></a> &nbsp;"+
+                                "<a href='#' onclick='del(\""+val+"\",\""+row.subclass+"\")'><i class='fa fa-fw fa-trash text-red'></i></a>"
+                    }}
+            ]
+        });
+        //ttable.on('init.dt', function () {});
+    })
+
+    function save(){
+        _id=$("#_id").val()
+        topclass=$("#topclass").val()
+        var clearArr = [];
+        var clearArr2 = [];
+        $("#select4 option").each(function(i,val){
+            clearArr[i] = this.value
+        })
+        $("#select3 option").each(function(i,val){
+            clearArr2[i] = this.value
+        })
+        var subclass=$("#subclass").val()
+        var fields = JSON.stringify(clearArr)
+        var fields2 = JSON.stringify(clearArr2)
+        if(topclass == "" || clearArr.length==0){
+            alert("表单填写不完整!");
+            return false;
+        }
+        $.ajax({
+            url:"/admin/infotype/save",
+            type:"post",
+            data:{"topclass":topclass,"subclass":subclass,"fields":fields,"fields2":fields2,"_id":_id},
+            success:function(r){
+                if(r.rep){
+                    $("#userform")[0].reset();
+                    $("#modal-info").modal("hide");
+                    ttable.ajax.reload();
+                }else{
+                    alert("保存失败,可能是要添加的分类已存在");
+                }
+            }
+        })
+    }
+    function del(_id,subclass){
+        showConfirm("确定删除?", function() {
+            $.ajax({
+                url:"/admin/infotype/del",
+                type:"post",
+                data:{"_id":_id,"subclass":subclass},
+                success:function(r){
+                    if(r.rep){
+                        ttable.ajax.reload();
+                    }else{
+                        showTip("删除失败", 1000, function() {});
+                    }
+                }
+            })
+        });
+    }
+    function edit(_id,subclass){
+        $("#topclass").empty()
+        $("#subclass").empty()
+        $("#select3").empty();
+        $("#select4").empty();
+        $("#_id").val(_id)
+        console.log(_id,subclass)
+        $.ajax({
+            url:"/admin/infotype/select",
+            type:"post",
+            data:{"_id":_id,"subclass":subclass},
+            success:function(r){
+                console.log(r)
+                if(r){
+                    $("#topclass").append("<option value="+r.topclass+">"+r.topclass+"</option>")
+                    $("#topclass").attr("disabled",true);
+                    $("#subclass").append("<option value="+r.subclass+">"+r.subclass+"</option>")
+                    $("#subclass").attr("disabled",true);
+                    for(var a=0;a<r.fields.length;a++){
+                        $("#select4").append("<option  value='"+r.fields[a].s_field+"'>"+r.fields[a].s_name+"</option>");
+                    }
+                    for(var a=0;a<r.fields2.length;a++){
+                        $("#select3").append("<option  value='"+r.fields2[a].s_field+"'>"+r.fields2[a].s_name+"</option>");
+                    }
+                }
+            }
+        })
+        $("#modal-info").modal("show");
+    }
+    function topfunc() {
+        $("#subclass").empty()
+        var top=$("#topclass").val()
+        var topmap={"top":top}
+        $.post("/admin/subclass/data",topmap,function (data,status) {
+            if(data.length!=0){
+                for(var a=0;a<data.data.subclass.length;a++) {
+                    $("#subclass").append("<option value="+data.data.subclass[a]+">"+data.data.subclass[a]+"</option>")
+                }
+            }
+        })
+    }
+    function formReset(){
+        $("#_id").val("")
+        $("#topclass").empty()
+        $("#topclass").attr("disabled",false);
+        $("#subclass").empty()
+        $("#subclass").attr("disabled",false);
+        $("#select3").empty();
+        $("#select4").empty();
+        $.post("/admin/topclass/data",'',function (data,status) {
+            $("#topclass").append("<option value=''>--请选择--</option>")
+            for(var a=0;a<data.data.length;a++) {
+                $("#topclass").append("<option value="+data.data[a].topclass+">"+data.data[a].topclass+"</option>")
+            }
+        })
+        $.post("/admin/fields/data",'',function (data,status) {
+            for(var a=0;a<data.data.length;a++) {
+                $("#select3").append("<option value="+data.data[a].s_field+">"+data.data[a].s_name+"</option>")
+            }
+        })
+        $("#modal-info-addclear").modal("show");
+    }
+    $("#selectclear2 #right2").click(function(){
+        $("#select3 option:selected").appendTo("#select4");
+    });
+    //左移
+    $("#selectclear2 #left2").click(function(){
+        $("#select4 option:selected").appendTo("#select3");
+    });
+    $("#selectclear2 #up2,#selectclear2 #down2").click(function() {
+        var $opt = $("#select4 option:selected:first");
+        if (!$opt.length){
+            return;
+        }
+        if (this.id == "up2"){
+            $opt.prev().before($opt);
+        }else{
+            $opt.next().after($opt);
+        }
+    });
+    //双击右移
+    $("#selectclear2 #select3").dblclick(function(){
+        $("#selectclear2 #select3 option:selected").appendTo("#select4");
+    });
+    //双击左移
+    $("#selectclear2 #select4").dblclick(function(){
+        $("#selectclear2 #select4 option:selected").appendTo("#select3");
+    });
+</script>

+ 0 - 1
src/web/templates/admin/com_memu.html

@@ -51,7 +51,6 @@ $(function () {
 	$.post('/admin/menu','',function (data,status) {
 		for(var a=0;a<data.data.length;a++) {
             var info=data.data[a]
-            console.log(info)
 		    if (info.secondmenu){
                 var str=""
                 for(var sec=1;sec<=Object.keys(info.secondmenu).length;sec++){

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

@@ -86,7 +86,7 @@
 {{template "footer"}}
 
 <script>
-    menuActive("secondmenu")
+    menuActive("menu")
     $(function () {
         ttable=$('#dataTable').DataTable({
             "paging"      : true,

+ 3 - 2
src/web/templates/admin/version.html

@@ -174,8 +174,9 @@ $(function () {
 			}},
 			{ "data":"_id","width":"25%",render:function(val,a,row){
 				return '<div class="btn-group">'+
-						'<a class="btn btn-sm btn-success" href="/admin/version/info?vid='+val+'" >属性配置</a>'+
-						'<a class="btn btn-sm btn-info" href="/admin/version/pkginfo?vid='+val+'" >分包配置</a>'+
+						'<a class="btn btn-sm btn-success" href="/admin/version/info?vid='+val+'" >属性</a>'+
+						'<a class="btn btn-sm btn-warning" href="/admin/version/blockinfo?vid='+val+'" >分块</a>'+
+						'<a class="btn btn-sm btn-info" href="/admin/version/pkginfo?vid='+val+'" >分包</a>'+
 						/*'<a class="btn btn-sm btn-primary opr" opr="edit">编&nbsp;&nbsp;辑1</a>'+*/
 						"<a class=\"btn btn-sm btn-primary opr\" href='#' onclick=\"edit('"+val+"')\">编&nbsp;&nbsp;辑</a> &nbsp;"+
 						'<a class="btn btn-sm btn-danger" href="#" onclick="del(\''+val+'\',\''+row["version"]+'\')">删&nbsp;&nbsp;除</a>'