ソースを参照

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

apple 5 年 前
コミット
e3188b87a7

+ 57 - 0
src/jy/admin/rule.go

@@ -119,6 +119,19 @@ func init() {
 	Admin.POST("/logicore/del", RuleLogicCoreDel)
 	Admin.POST("/logicore/use", RuleLogicCoreUse)
 
+	Admin.GET("/logickv", func(c *gin.Context) {
+		vid := c.Query("vid")
+		pid := c.Query("pid")
+		sid := c.Query("sid")
+		//查询属性字段
+		tmp, _ := Mgo.FindById("versioninfo", pid, `{"s_field":1}`)
+		c.HTML(200, "rule_logickv.html", gin.H{"vid": vid, "pid": pid, "sid": sid, "field": (*tmp)["s_field"]})
+	})
+	Admin.POST("/logickv/data", RuleLogicCoreDataKv)
+	Admin.POST("/logickv/save", RuleLogicCoreSaveKv)
+	Admin.POST("/logickv/del", RuleLogicCoreDelKv)
+	Admin.POST("/logickv/use", RuleLogicCoreUseKv)
+
 	Admin.GET("/pkglogicback", func(c *gin.Context) {
 		vid := c.Query("vid")
 		pid := c.Query("pid")
@@ -439,6 +452,13 @@ func RuleLogicCoreData(c *gin.Context) {
 	data, _ := Mgo.Find("rule_logicore", `{"sid":"`+sid+`","delete":false}`, `{"_id":-1}`, nil, false, -1, -1)
 	c.JSON(200, gin.H{"data": data, "vid": vid, "pid": pid, "sid": sid})
 }
+func RuleLogicCoreDataKv(c *gin.Context) {
+	vid, _ := c.GetPostForm("vid")
+	pid, _ := c.GetPostForm("pid")
+	sid, _ := c.GetPostForm("sid")
+	data, _ := Mgo.Find("rule_logickv", `{"sid":"`+sid+`","delete":false}`, `{"_id":-1}`, nil, false, -1, -1)
+	c.JSON(200, gin.H{"data": data, "vid": vid, "pid": pid, "sid": sid})
+}
 func RuleLogicCoreSave(c *gin.Context) {
 	data := GetPostForm(c)
 	_id, _ := c.GetPostForm("_id")
@@ -464,18 +484,55 @@ func RuleLogicCoreSave(c *gin.Context) {
 	}
 	c.JSON(200, gin.H{"rep": b})
 }
+func RuleLogicCoreSaveKv(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("rule_logickv", data) != ""
+	} else {
+		data["l_lasttime"] = time.Now().Unix()
+		b = Mgo.Update("rule_logickv", `{"_id":"`+_id+`"}`, map[string]interface{}{
+			"$set": data,
+		}, true, false)
+	}
+	c.JSON(200, gin.H{"rep": b})
+}
 func RuleLogicCoreDel(c *gin.Context) {
 	_id, _ := c.GetPostForm("_id")
 	//b := Mgo.Del("rule_logicore", `{"_id":"`+_id+`"}`)
 	b := Mgo.UpdateById("rule_logicore", _id, `{"$set":{"delete":true}}`)
 	c.JSON(200, gin.H{"rep": b})
 }
+func RuleLogicCoreDelKv(c *gin.Context) {
+	_id, _ := c.GetPostForm("_id")
+	//b := Mgo.Del("rule_logicore", `{"_id":"`+_id+`"}`)
+	b := Mgo.UpdateById("rule_logickv", _id, `{"$set":{"delete":true}}`)
+	c.JSON(200, gin.H{"rep": b})
+}
 func RuleLogicCoreUse(c *gin.Context) {
 	_id, _ := c.GetPostForm("_id")
 	isuse, _ := c.GetPostForm("isuse")
 	b := Mgo.UpdateById("rule_logicore", _id, `{"$set":{"isuse":`+isuse+`}}`)
 	c.JSON(200, gin.H{"rep": b})
 }
+func RuleLogicCoreUseKv(c *gin.Context) {
+	_id, _ := c.GetPostForm("_id")
+	isuse, _ := c.GetPostForm("isuse")
+	b := Mgo.UpdateById("rule_logickv", _id, `{"$set":{"isuse":`+isuse+`}}`)
+	c.JSON(200, gin.H{"rep": b})
+}
 
 func DelVersionInfo(vid string, isSite bool) { //刪除属性配置
 	var versioninfodb string

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

@@ -91,6 +91,7 @@ func init() {
 				go Mgo.Del("site_rule_logic", bson.M{"pid": (*vinfotmp)["_id"].(bson.ObjectId).Hex(),"vid":util.ObjToString((*vstmp)["vid"])})
 				go Mgo.Del("site_rule_logicback", bson.M{"pid": (*vinfotmp)["_id"].(bson.ObjectId).Hex(),"vid":util.ObjToString((*vstmp)["vid"])})
 				go Mgo.Del("site_rule_logicore", bson.M{"pid": (*vinfotmp)["_id"].(bson.ObjectId).Hex(),"vid":util.ObjToString((*vstmp)["vid"])})
+				go Mgo.Del("site_rule_logickv", bson.M{"pid": (*vinfotmp)["_id"].(bson.ObjectId).Hex(),"vid":util.ObjToString((*vstmp)["vid"])})
 				go Mgo.Del("site_rule_logicpre", bson.M{"pid": (*vinfotmp)["_id"].(bson.ObjectId).Hex(),"vid":util.ObjToString((*vstmp)["vid"])})
 			}
 			go Mgo.Del("site_versioninfo", bson.M{"pid": _id,"vid":util.ObjToString((*vstmp)["vid"])})
@@ -282,6 +283,15 @@ func init() {
 		tmp, _ := Mgo.FindById("site_versioninfo", pid, `{"s_field":1}`)
 		c.HTML(200, "site_rule_logicore.html", gin.H{"vid": vid, "pid": pid, "sid": sid, "field": (*tmp)["s_field"], "pzid": (*verinfo)["pid"]})
 	})
+	Admin.GET("/site_management/logickv", func(c *gin.Context) {
+		vid := c.Query("vid")
+		pid := c.Query("pid")
+		sid := c.Query("sid")
+		verinfo, _ := Mgo.FindById("site_versioninfo", pid, bson.M{"pid": 1})
+		//查询属性字段
+		tmp, _ := Mgo.FindById("site_versioninfo", pid, `{"s_field":1}`)
+		c.HTML(200, "site_rule_logickv.html", gin.H{"vid": vid, "pid": pid, "sid": sid, "field": (*tmp)["s_field"], "pzid": (*verinfo)["pid"]})
+	})
 	//抽取规则
 	Admin.POST("/site_management/logicore/data", func(c *gin.Context) {
 		vid, _ := c.GetPostForm("vid")
@@ -290,6 +300,14 @@ func init() {
 		data, _ := Mgo.Find("site_rule_logicore", `{"sid":"`+sid+`","delete":false}`, `{"_id":-1}`, nil, false, -1, -1)
 		c.JSON(200, gin.H{"data": data, "vid": vid, "pid": pid, "sid": sid})
 	})
+	//抽取规则
+	Admin.POST("/site_management/logickv/data", func(c *gin.Context) {
+		vid, _ := c.GetPostForm("vid")
+		pid, _ := c.GetPostForm("pid")
+		sid, _ := c.GetPostForm("sid")
+		data, _ := Mgo.Find("site_rule_logickv", `{"sid":"`+sid+`","delete":false}`, `{"_id":-1}`, nil, false, -1, -1)
+		c.JSON(200, gin.H{"data": data, "vid": vid, "pid": pid, "sid": sid})
+	})
 	Admin.POST("/site_management/logicore/save", func(c *gin.Context) {
 		data := GetPostForm(c)
 		_id, _ := c.GetPostForm("_id")
@@ -315,18 +333,55 @@ func init() {
 		}
 		c.JSON(200, gin.H{"rep": b})
 	})
+	Admin.POST("/site_management/logickv/save", func(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 = getSyncIndex(E_CE)
+			} else { //抽取逻辑脚本
+				code = getSyncIndex(E_CL)
+			}
+			data["s_code"] = code
+			b = Mgo.Save("site_rule_logickv", data) != ""
+		} else {
+			data["l_lasttime"] = time.Now().Unix()
+			b = Mgo.Update("site_rule_logickv", `{"_id":"`+_id+`"}`, map[string]interface{}{
+				"$set": data,
+			}, true, false)
+		}
+		c.JSON(200, gin.H{"rep": b})
+	})
 	Admin.POST("/site_management/logicore/del", func(c *gin.Context) {
 		_id, _ := c.GetPostForm("_id")
 		//b := Mgo.Del("rule_logicore", `{"_id":"`+_id+`"}`)
 		b := Mgo.UpdateById("site_rule_logicore", _id, `{"$set":{"delete":true}}`)
 		c.JSON(200, gin.H{"rep": b})
 	})
+	Admin.POST("/site_management/logickv/del", func(c *gin.Context) {
+		_id, _ := c.GetPostForm("_id")
+		//b := Mgo.Del("rule_logicore", `{"_id":"`+_id+`"}`)
+		b := Mgo.UpdateById("site_rule_logickv", _id, `{"$set":{"delete":true}}`)
+		c.JSON(200, gin.H{"rep": b})
+	})
 	Admin.POST("/site_management/logicore/use", func(c *gin.Context) {
 		_id, _ := c.GetPostForm("_id")
 		isuse, _ := c.GetPostForm("isuse")
 		b := Mgo.UpdateById("site_rule_logicore", _id, `{"$set":{"isuse":`+isuse+`}}`)
 		c.JSON(200, gin.H{"rep": b})
 	})
+	Admin.POST("/site_management/logickv/use", func(c *gin.Context) {
+		_id, _ := c.GetPostForm("_id")
+		isuse, _ := c.GetPostForm("isuse")
+		b := Mgo.UpdateById("site_rule_logickv", _id, `{"$set":{"isuse":`+isuse+`}}`)
+		c.JSON(200, gin.H{"rep": b})
+	})
 
 	//后置规则
 	Admin.GET("/site_management/logicback", func(c *gin.Context) {

+ 16 - 1
src/jy/admin/version.go

@@ -645,19 +645,21 @@ func copyPkgRules(vid, pid, s_field, oldvid, s_username string) {
 //克隆版本Field
 func copyFieldRules(vid, pid, s_field, oldvid, s_username string, isSite bool) {
 	log.Println(vid, pid, s_field, oldvid, s_username)
-	var versioninfo, rule_logic, rule_logicpre, rule_logicore, rule_logicback string
+	var versioninfo, rule_logic, rule_logicpre, rule_logicore, rule_logicback,rule_logickv string
 	if isSite {
 		versioninfo = "site_versioninfo"
 		rule_logic = "site_rule_logic"
 		rule_logicpre = "site_rule_logicpre"
 		rule_logicore = "site_rule_logicore"
 		rule_logicback = "site_rule_logicback"
+		rule_logickv = "site_rule_logickv"
 	} else {
 		versioninfo = "versioninfo"
 		rule_logic = "rule_logic"
 		rule_logicpre = "rule_logicpre"
 		rule_logicore = "rule_logicore"
 		rule_logicback = "rule_logicback"
+		rule_logickv = "rule_logickv"
 	}
 	tmp, _ := Mgo.FindOne(versioninfo, `{"vid":"`+oldvid+`","s_field":"`+s_field+`","delete":false}`)
 	oldpid := qu.BsonIdToSId((*tmp)["_id"])
@@ -699,6 +701,19 @@ func copyFieldRules(vid, pid, s_field, oldvid, s_username string, isSite bool) {
 				v["l_lasttime"] = time.Now().Unix()
 				Mgo.Save(rule_logicore, v)
 			}
+			//克隆kv抽取规则
+			kvlist, _ := Mgo.Find(rule_logickv, `{"sid":"`+oldsid+`","delete":false}`, nil, nil, false, -1, -1)
+			for _, v := range *kvlist {
+				delete(v, "_id")
+				v["vid"] = vid
+				v["pid"] = pid
+				v["sid"] = sid
+				v["s_code"] = util.GetSyncIndex(getCode(v["s_code"].(string)))
+				v["s_username"] = s_username
+				v["l_createtime"] = time.Now().Unix()
+				v["l_lasttime"] = time.Now().Unix()
+				Mgo.Save(rule_logickv, v)
+			}
 			//克隆过滤规则
 			blist, _ := Mgo.Find(rule_logicback, `{"sid":"`+oldsid+`","delete":false}`, nil, nil, false, -1, -1)
 			for _, v := range *blist {

+ 59 - 17
src/jy/extract/extract.go

@@ -421,13 +421,13 @@ func (e *ExtractTask) ExtractProcess(j, jf *ju.Job, isSite bool) {
 			//合并数据
 			j.Block = append(j.Block, tmpj.Block...)
 			j.Winnerorder = append(j.Winnerorder, tmpj.Winnerorder...)
-			for tmpk,_:= range j.Result{
-				if len(tmpj.Result[tmpk]) >0 {
+			for tmpk, _ := range j.Result {
+				if len(tmpj.Result[tmpk]) > 0 {
 					j.Result[tmpk] = append(j.Result[tmpk], tmpj.Result[tmpk]...)
 				}
 			}
-			for tmpk ,_ :=range tmpj.Result{
-				if len(j.Result[tmpk]) == 0{
+			for tmpk, _ := range tmpj.Result {
+				if len(j.Result[tmpk]) == 0 {
 					j.Result[tmpk] = append(j.Result[tmpk], tmpj.Result[tmpk]...)
 				}
 			}
@@ -503,6 +503,10 @@ func (e *ExtractTask) ExtractDetail(j *ju.Job, isSite bool, codeSite string) {
 				for _, v := range vc.RuleBacks {
 					ExtRegBack(j, v, e.TaskInfo)
 				}
+				//kv规则
+				for _, v := range vc.KVRuleCores {
+					ExtRuleKV(j, v, e.TaskInfo)
+				}
 				// log.Debug("抽取-后置规则", tmp)
 
 				//项目名称未能抽取到,标题来凑
@@ -517,7 +521,7 @@ func (e *ExtractTask) ExtractDetail(j *ju.Job, isSite bool, codeSite string) {
 						}
 						if isextitle { //标题加入选举
 							field := &ju.ExtField{Field: vc.Field, Code: vc.Id + "_title", RuleText: "title", Type: "title", MatchType: "title", ExtFrom: vc.ExtFrom, SourceValue: j.Title, Value: j.Title}
-							if isSite{
+							if isSite {
 								field.Score = 1
 							}
 							j.Result[vc.Field] = append(j.Result[vc.Field], field)
@@ -743,10 +747,10 @@ func ExtRuleCore(doc map[string]interface{}, e *ExtractTask, vc *RuleCore, j *ju
 									SourceValue: vv.Key,
 									Value:       text,
 								}
-								if isSite{
+								if isSite {
 									tmp.Score = 1
 								}
-								j.Result[vc.Field] = append(j.Result[vc.Field],tmp)
+								j.Result[vc.Field] = append(j.Result[vc.Field], tmp)
 							}
 						}
 					}
@@ -952,10 +956,10 @@ func extractFromKv(field, fieldname string, blocks []*ju.Block, vc *RuleCore, kv
 }
 
 //正则提取结果
-func extRegCoreToResult(extfrom, text string, tag *map[string]string, j *ju.Job, vre *RegLuaInfo,isSite bool) map[string][]map[string]interface{} {
+func extRegCoreToResult(extfrom, text string, tag *map[string]string, j *ju.Job, vre *RegLuaInfo, isSite bool) map[string][]map[string]interface{} {
 	defer qu.Catch()
 	var score int
-	if isSite{
+	if isSite {
 		score = 1
 	}
 	extinfo := map[string][]map[string]interface{}{}
@@ -1027,7 +1031,7 @@ func extRegCoreToResult(extfrom, text string, tag *map[string]string, j *ju.Job,
 						"type":      "regexp",
 						"matchtype": "regcontent",
 						"blocktag":  *tag,
-						"score" :score,
+						"score":     score,
 					}
 					tmps = append(tmps, tmp)
 
@@ -1064,7 +1068,7 @@ func extRegCoreToResult(extfrom, text string, tag *map[string]string, j *ju.Job,
 				"type":      "regexp",
 				"matchtype": "regcontent",
 				"blocktag":  *tag,
-				"score" :score,
+				"score":     score,
 			}
 			tmps = append(tmps, tmp)
 			extinfo[vre.Field] = tmps
@@ -1136,8 +1140,8 @@ func ExtRegBack(j *ju.Job, in *RegLuaInfo, t *TaskInfo) {
 						"value":     text,
 					})
 				}
-				extinfo[in.Field] = exts
-				if len(extinfo) > 0 {
+				if len(exts) > 0 {
+					extinfo[in.Field] = exts
 					AddExtLog("clear", j.SourceMid, tmp, extinfo, in, t) //抽取日志
 				}
 			}
@@ -1166,10 +1170,48 @@ func ExtRegBack(j *ju.Job, in *RegLuaInfo, t *TaskInfo) {
 						"value":     text,
 					})
 				}
-				extinfo[key] = exts
+				if len(exts) > 0 {
+					extinfo[key] = exts
+					AddExtLog("clear", j.SourceMid, j.Result, extinfo, in, t) //抽取日志
+				}
 			}
-			if len(extinfo) > 0 {
-				AddExtLog("clear", j.SourceMid, j.Result, extinfo, in, t) //抽取日志
+		}
+	}
+}
+
+//KV过滤
+func ExtRuleKV(j *ju.Job, in *RegLuaInfo, t *TaskInfo) {
+	defer qu.Catch()
+	extinfo := map[string]interface{}{}
+	if in.Field != "" {
+		if j.Result[in.Field] != nil {
+			tmp := j.Result[in.Field]
+			exts := []interface{}{}
+			for k, v := range tmp {
+				if v.Type != "table" && !strings.Contains(v.Type, "colon") && !strings.Contains(v.Type, "space") {
+					continue
+				}
+				text := qu.ObjToString(v.Value)
+				if text != "" {
+					text = in.RegPreBac.Reg.ReplaceAllString(text, in.RegPreBac.Replace)
+				}
+				if text == qu.ObjToString(v.Value) { //值未发生改变,不存日志
+					continue
+				}
+				j.Result[in.Field][k].Value = text
+				exts = append(exts, map[string]interface{}{
+					"field":     v.Field,
+					"code":      v.Code,
+					"ruletext":  v.RuleText,
+					"type":      v.Type,
+					"matchtype": v.MatchType,
+					"extfrom":   v.ExtFrom,
+					"value":     text,
+				})
+			}
+			if len(exts) > 0 {
+				extinfo[in.Field] = exts
+				AddExtLog("clear", j.SourceMid, tmp, extinfo, in, t) //抽取日志
 			}
 		}
 	}
@@ -1726,7 +1768,7 @@ func resetWinnerorder(j *ju.Job) {
 	if len(j.Winnerorder) == 0 {
 		return
 	}
-	maxlen := len(j.Winnerorder)-1
+	maxlen := len(j.Winnerorder) - 1
 	//中标单位
 	i := 0
 	winners := []*ju.ExtField{}

+ 51 - 12
src/jy/extract/extractInit.go

@@ -33,14 +33,15 @@ type ExtReg struct {
 	NumSign    int //正负修正标记,例如浮动率(上浮正1、下浮负-1)
 }
 type RuleCore struct {
-	Id        string            //id
-	Field     string            //逻辑字段
-	LuaLogic  string            //进入逻辑
-	ExtFrom   string            //从哪个字段抽取
-	RulePres  []*RegLuaInfo     //抽取前置规则
-	RuleBacks []*RegLuaInfo     //抽取后置规则
-	RuleCores []*RegLuaInfo     //抽取规则
-	LFields   map[string]string //所有字段属性组
+	Id          string            //id
+	Field       string            //逻辑字段
+	LuaLogic    string            //进入逻辑
+	ExtFrom     string            //从哪个字段抽取
+	RulePres    []*RegLuaInfo     //抽取前置规则
+	RuleBacks   []*RegLuaInfo     //抽取后置规则
+	RuleCores   []*RegLuaInfo     //抽取规则
+	KVRuleCores []*RegLuaInfo     //KV抽取清理规则
+	LFields     map[string]string //所有字段属性组
 }
 
 type Tag struct {
@@ -246,11 +247,11 @@ func (e *ExtractTask) InitSite() {
 		if vv, ok := v["site_script"].([]interface{}); ok {
 			for _, vvv := range vv {
 				e.Luacodes.Store(vvv, map[string]interface{}{})
-				e.SiteMerge.Store(vvv,v["ismerge"].(bool))
+				e.SiteMerge.Store(vvv, v["ismerge"].(bool))
 			}
 		} else if vv, ok := v["site_script"].(interface{}); ok {
 			e.Luacodes.Store(vv, map[string]interface{}{})
-			e.SiteMerge.Store(vv,v["ismerge"].(bool))
+			e.SiteMerge.Store(vv, v["ismerge"].(bool))
 		}
 	}
 }
@@ -384,7 +385,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 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"
@@ -392,6 +393,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"
 		e.SiteRuleCores = make(map[string]map[string][]*RuleCore)
 	} else {
 		versioninfodb = "versioninfo"
@@ -399,6 +401,7 @@ func (e *ExtractTask) InitRuleCore(isSite bool) {
 		rule_logicpredb = "rule_logicpre"
 		rule_logicbackdb = "rule_logicback"
 		rule_logicoredb = "rule_logicore"
+		rule_logickvdb= "rule_logickv"
 		e.RuleCores = make(map[string]map[string][]*RuleCore)
 	}
 
@@ -549,7 +552,43 @@ func (e *ExtractTask) InitRuleCore(isSite bool) {
 				}
 			}
 			rcore.RuleCores = ruleCores
-			//
+			//kv规则
+			kvRuleCores := []*RegLuaInfo{}
+			kvlist, _ := db.Mgo.Find(rule_logickvdb, `{"sid":"`+qu.BsonIdToSId(vv["_id"])+`","delete":false}`, nil, nil, false, -1, -1)
+			for _, v := range *kvlist {
+				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),
+				}
+				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: ""}
+					}
+					kvRuleCores = append(kvRuleCores, rinfo)
+				}, func(err interface{}) {
+					log.Debug(rinfo.Code, rinfo.Field, err)
+				})
+			}
+			rcore.KVRuleCores = kvRuleCores
 			if fieldrules[s_field] == nil {
 				fieldrules[s_field] = []*RuleCore{}
 			}

+ 14 - 4
src/jy/extract/score.go

@@ -168,7 +168,7 @@ func ScoreFields(j *ju.Job, ftag map[string][]*Tag) map[string][]*ju.ExtField {
 			//kv权重打分
 			if fieldscore != nil { //指定抽取属性打分配置
 				if tmpsvalue.Type == "colon" || tmpsvalue.Type == "space" || tmpsvalue.Type == "table" {
-					if taglength == 0{
+					if taglength == 0 {
 						continue
 					}
 					weightscore := ju.FloatFormat(float64(qu.Float64All(fieldscore["kvweight"]))+float64(tmps[tmpsindex].Weight)/float64(taglength), 4)
@@ -179,7 +179,7 @@ func ScoreFields(j *ju.Job, ftag map[string][]*Tag) map[string][]*ju.ExtField {
 				}
 			} else {
 				if tmpsvalue.Type == "colon" || tmpsvalue.Type == "space" || tmpsvalue.Type == "table" {
-					if taglength == 0{
+					if taglength == 0 {
 						continue
 					}
 					weightscore := ju.FloatFormat(float64(qu.Float64All(CommonScore["kvweight"]))+float64(tmps[tmpsindex].Weight)/float64(taglength), 4)
@@ -270,7 +270,7 @@ func ScoreFields(j *ju.Job, ftag map[string][]*Tag) map[string][]*ju.ExtField {
 				max := qu.IntAll(scoreRule["max"])
 				val := qu.IntAll(tmpsvalue.Value)
 				scores, _ := scoreRule["score"].([]interface{})
-				if len(scores) < 3 || val == 0{
+				if len(scores) < 3 || val == 0 {
 					continue
 				}
 				if val < min && 0 < val {
@@ -324,12 +324,13 @@ func ScoreFields(j *ju.Job, ftag map[string][]*Tag) map[string][]*ju.ExtField {
 //项目编号权重清理
 func projectWeightClear(tmps []*ju.ExtField) []*ju.ExtField {
 	newList := make([]*ju.ExtField, 0)
-	if len(tmps)<1{
+	if len(tmps) < 1 {
 		return newList
 	}
 	ju.Sort(tmps)
 	tmpWeight := -999 //记录最大权重
 	tmpIndex := -999  //记录最大权重下标
+	vmap := make(map[string]int, 0)
 	for i, v := range tmps {
 		if v.Weight == 0 {
 			newList = append(newList, v)
@@ -337,10 +338,19 @@ func projectWeightClear(tmps []*ju.ExtField) []*ju.ExtField {
 		} else if v.Weight > tmpWeight {
 			tmpWeight = v.Weight
 			tmpIndex = i
+		} else if v.Weight == tmpWeight {
+			if utf8.RuneCountInString(qu.ObjToString(v.Value)) >= 5 && utf8.RuneCountInString(qu.ObjToString(v.Value)) <= 38 && v.Value != tmps[tmpIndex].Value {
+				vmap[qu.ObjToString(v.Value)] = i
+			}
 		}
 	}
 	if tmpIndex != -999 {
 		newList = append(newList, tmps[tmpIndex])
 	}
+	if len(vmap) > 0 {
+		for _, v := range vmap {
+			newList = append(newList, tmps[v])
+		}
+	}
 	return newList
 }

+ 3 - 0
src/jy/pretreated/analytable.go

@@ -1691,6 +1691,9 @@ 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) == ""{
+		return
+	}
 	near := table.FindNear(td, direct)
 	//	if near != nil {
 	//		fmt.Println("near----", near.Val, td.Val)

+ 1 - 1
src/jy/pretreated/tablev2.go

@@ -405,7 +405,7 @@ func (td *TD) tdIsHb(tr *TR, table *Table, bsontable,isSite bool,codeSite string
 			if lenval > 15 && !strings.Contains(txt, "采购代理机构名称、地址和联系方式") {
 				btw = false
 			}
-			if strings.Contains(td.Val, "个项目") {
+			if strings.Contains(td.Val, "个项目") ||strings.Contains(td.Val, "奥图码"){
 				must = false
 				btw = false
 			}

+ 1 - 1
src/res/fieldscore.json

@@ -147,7 +147,7 @@
         "negativewords": [
             {
                 "describe": "包含负分",
-                "regstr": "(附件|委托|代理|咨询|顾问|管理有限公司|管理顾问|招标失败|交易中心|不足|公告|变更|招标|废标|废止|流标|中标|评标|开标|供应商|金额|万元|元整|预算|报价|单价|第(\\d|一|二|三|四|五)(名|包)|排名|候选|确定|标段|(标|一|二|三|四|五)包|中选|成交|包号|(A|B|C|D|E|F|G)包|地址|详情|要求|推荐|名称|评审|得分|合同|平方米|公示期|结果|备注|说明|单位|代表|委托|工作日|营业(执|期)|通过|代码|电话|联系|条件|合理|费率|以上|以下|拟定|为|注:|\\d[\\s]{0,10}(\\.|元|包|米|平米|平方米|吨|辆|千克|克|毫克|毫升|公升|套|件|瓶|箱|只|台|年|月|日|天|号)|(:|:|;|;|?|¥|\\*|%)|^[a-zA-Z0-9-]{5,100}|^[a-zA-Z0-9-]{1,100}$|[a-zA-Z0-9-]{10,100})",
+                "regstr": "(标人|附件|委托|代理|咨询|顾问|管理有限公司|管理顾问|招标失败|交易中心|不足|公告|变更|招标|废标|废止|流标|中标|评标|开标|供应商|金额|万元|元整|预算|报价|单价|第(\\d|一|二|三|四|五)(名|包)|排名|候选|确定|标段|(标|一|二|三|四|五)包|中选|成交|包号|(A|B|C|D|E|F|G)包|地址|详情|要求|推荐|名称|评审|得分|合同|平方米|公示期|结果|备注|说明|单位|代表|委托|工作日|营业(执|期)|通过|代码|电话|联系|条件|合理|费率|以上|以下|拟定|为|注:|\\d[\\s]{0,10}(\\.|元|包|米|平米|平方米|吨|辆|千克|克|毫克|毫升|公升|套|件|瓶|箱|只|台|年|月|日|天|号)|(:|:|;|;|?|¥|\\*|%)|^[a-zA-Z0-9-]{5,100}|^[a-zA-Z0-9-]{1,100}$|[a-zA-Z0-9-]{10,100})",
                 "score": -5
             },
             {

+ 256 - 0
src/web/templates/admin/rule_logickv.html

@@ -0,0 +1,256 @@
+{{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/info?vid={{.vid}}&pid={{.pid}}">属性配置</a></li>
+		  <li><a href="/admin/rulelogic?vid={{.vid}}&pid={{.pid}}">抽取逻辑</a></li>
+		  <li class="active"><a href="/admin/logickv?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}">kv规则</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/logickv/data",
+			"type": "post",
+			"data":{"vid":{{.vid}},"pid":{{.pid}},"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/logickv/save",obj,function(data){
+										if(data&&data.rep){
+											window.location.href="/admin/logickv?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}"
+										}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}]
+				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"}]
+				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/backrule",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/ckv?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}&s_code="+obj.s_code
+								}
+							}]
+					bts = com.pushArry(bts,check)
+				}else{
+					_tit="新增规则"
+						obj={"vid":"{{.vid}}","pid":"{{.pid}}","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/logickv/del",
+			type:"post",
+			data:{"_id":_id},
+			success:function(r){
+				if(r.rep){				
+					window.location.href="/admin/logickv?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}";
+				}else{
+					showTip("删除失败", 1000);
+				}
+			}
+		})
+	});
+}
+function use(_id,utype){
+	smg=""
+	if(utype){
+		smg="确定启用?"
+	}else{
+		smg="确定停用?"
+	}
+	showConfirm(smg, function() {
+		$.ajax({
+			url:"/admin/logickv/use",
+			type:"post",
+			data:{"_id":_id,"isuse":utype},
+			success:function(r){
+				if(r.rep){				
+					window.location.reload()
+				}else{
+					showTip("启用失败", 1000, function() {});
+				}
+			}
+		})
+	});
+}
+</script>

+ 2 - 1
src/web/templates/admin/rule_logiclist.html

@@ -81,7 +81,8 @@ $(function () {
 				tmp = '<div class="btn-group">'+
 					'<a class="btn btn-sm btn-primary" href="/admin/logicpre?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">前置规则</a>'+
 					'<a class="btn btn-sm btn-success" href="/admin/logicore?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">抽取规则</a>'+
-					'<a class="btn btn-sm btn-info" href="/admin/logicback?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">后置规则</a>'+
+						'<a class="btn btn-sm btn-info" href="/admin/logicback?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">后置规则</a>'+
+						'<a class="btn btn-sm btn-warning" href="/admin/logickv?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">kv规则</a>'+
 					'</div>';
 				return  tmp
 			}},

+ 257 - 0
src/web/templates/admin/site_rule_logickv.html

@@ -0,0 +1,257 @@
+{{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/site_management?vid={{.vid}}">站点列表</a></li>
+			<li><a href="/admin/site_management/info?vid={{.vid}}&pid={{.pzid}}">属性配置</a></li>
+			<li><a href="/admin/site_management/rulelogic?vid={{.vid}}&pid={{.pid}}">抽取逻辑</a></li>
+		  <li class="active"><a href="/admin/site_management/logickv?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}">抽取规则</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/site_management/logickv/data",
+			"type": "post",
+			"data":{"vid":{{.vid}},"pid":{{.pid}},"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/site_management/logickv/save",obj,function(data){
+										if(data&&data.rep){
+											window.location.href="/admin/site_management/logickv?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}"
+										}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}]
+				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"}]
+				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/backrule",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/site_management/check/lua/core?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}&s_code="+obj.s_code
+								}
+							}]
+					bts = com.pushArry(bts,check)
+				}else{
+					_tit="新增规则"
+
+						obj={"vid":"{{.vid}}","pid":"{{.pid}}","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/site_management/logickv/del",
+			type:"post",
+			data:{"_id":_id},
+			success:function(r){
+				if(r.rep){				
+					window.location.href="/admin/site_management/logickv?vid={{.vid}}&pid={{.pid}}&sid={{.sid}}";
+				}else{
+					showTip("删除失败", 1000);
+				}
+			}
+		})
+	});
+}
+function use(_id,utype){
+	smg=""
+	if(utype){
+		smg="确定启用?"
+	}else{
+		smg="确定停用?"
+	}
+	showConfirm(smg, function() {
+		$.ajax({
+			url:"/admin/site_management/logickv/use",
+			type:"post",
+			data:{"_id":_id,"isuse":utype},
+			success:function(r){
+				if(r.rep){				
+					window.location.reload()
+				}else{
+					showTip("启用失败", 1000, function() {});
+				}
+			}
+		})
+	});
+}
+</script>

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

@@ -83,6 +83,7 @@ $(function () {
 						'<a class="btn btn-sm btn-primary" href="/admin/site_management/logicpre?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">前置规则</a>'+
 						'<a class="btn btn-sm btn-success" href="/admin/site_management/logicore?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">抽取规则</a>'+
 						'<a class="btn btn-sm btn-info" href="/admin/site_management/logicback?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">后置规则</a>'+
+						'<a class="btn btn-sm btn-warning" href="/admin/site_management/logickv?vid={{.vid}}&pid={{.pid}}&sid='+row._id+'">kv规则</a>'+
 						'</div>';
 				return  tmp
 			}},