Jianghan 5 年之前
父节点
当前提交
02f64508b2

+ 0 - 1
src/service/private_rule.go

@@ -352,7 +352,6 @@ func (r *Rule) ProductData() {
 		id := r.GetString("id")
 		tag, _ := Mgo.FindById("tags", id, `{}`)
 		err, count := UtilEsFind(*tag)
-		qu.Debug(err)
 		if err == nil {
 			rep = true
 		}

+ 100 - 2
src/service/tag_rule_service.go

@@ -1,10 +1,12 @@
 package service
 
 import (
+	"encoding/json"
 	"github.com/go-xweb/xweb"
 	"io/ioutil"
 	qu "qfw/util"
 	"strings"
+	"time"
 
 	. "util"
 
@@ -23,6 +25,7 @@ type TagRule struct {
 	tagEdit   xweb.Mapper `xweb:"/service/tag_rule/edit"`   //编辑
 	tagSave   xweb.Mapper `xweb:"/service/tag_rule/save"`   //保存
 	tagImport xweb.Mapper `xweb:"/service/tag_rule/import"` //导入
+	tagSetup  xweb.Mapper `xweb:"/service/tag_rule/setup"`  //启用停用
 }
 
 func (r *TagRule) TagList() {
@@ -51,7 +54,8 @@ func (r *TagRule) TagList() {
 			"recordsTotal":    count,
 		})
 	} else {
-		r.T["preview_href"] = PreviewHref
+		r.T["tagFieldMap"] = TagFieldMap
+		r.T["taskTypeMap"] = TaskTypeMap
 		r.Render("private/tag_rule_list.html", &r.T)
 	}
 }
@@ -61,11 +65,88 @@ func (r *TagRule) TagCreate() {
 	if r.Method() == "POST" {
 
 	} else {
-
+		r.T["tagFieldMap"] = TagFieldMap
+		r.T["taskTypeMap"] = TaskTypeMap
+		r.T["matchTypeMap"] = MatchTypeMap
 		r.Render("private/tag_rule_create.html", &r.T)
 	}
 }
 
+func (r *TagRule) TagEdit() {
+	defer qu.Catch()
+	id := r.GetString("id")         //标签列表编辑
+	query := bson.M{}
+	query["_id"] = qu.StringTOBsonId(id)
+	data, _ := Mgo.FindOneByField("tagrule", query, `{}`)
+	(*data)["id"] = qu.BsonIdToSId((*data)["_id"])
+	r.T["data"] = *data
+	r.T["tagFieldMap"] = TagFieldMap
+	r.T["taskTypeMap"] = TaskTypeMap
+	r.T["matchTypeMap"] = MatchTypeMap
+	r.Render("private/tag_rule_edit.html", &r.T)
+}
+
+func (r *TagRule) TagSave() {
+	defer qu.Catch()
+	if r.Method() == "POST" {
+		user := r.GetSession("user").(map[string]interface{})
+		data := GetPostForm(r.Request)
+		id := qu.ObjToString(data["id"])
+		delete(data, "id")
+		var oList []map[string]interface{}
+		oListstr := qu.ObjToString(data["o_list"])
+		json.Unmarshal([]byte(oListstr), &oList)
+		data["o_list"] = oList
+		i_createtime := time.Now().Unix()
+		data["i_updatetime"] = i_createtime
+		data["s_updateuser"] = user["name"]
+		if id == "" { //新建
+			data["i_createtime"] = i_createtime
+			data["s_createuser"] = user["name"]
+			data["i_isuse"] = 0
+			data["b_delete"] = false
+		}
+		id, rep := updateDbXf2(id, data)
+		r.ServeJson(map[string]interface{}{
+			"id":        id,
+			"rep":       rep,
+		})
+	}
+}
+
+func (r *TagRule) TagDel() {
+	defer qu.Catch()
+	_id := r.GetString("_id")
+	set := bson.M{
+		"$set": bson.M{
+			"b_delete": true,
+		},
+	}
+	b := Mgo.UpdateById("tagrule", _id, set)
+	r.ServeJson(map[string]interface{}{
+		"rep": b,
+	})
+}
+
+func updateDbXf2(id string, rdata map[string]interface{}) (rid string, rep bool) {
+	defer qu.Catch()
+	if id == "" {
+		rid = Mgo.Save("tagrule", rdata)
+		if rid != "" {
+			rep = true
+		} else {
+			rep = false
+		}
+	} else {
+		rid = id
+		query := bson.M{
+			"_id": qu.StringTOBsonId(id),
+		}
+		rep = Mgo.Update("tagrule", query, bson.M{"$set": rdata}, false, false)
+	}
+	return
+}
+
 func (r *TagRule) TagImport() {
 	defer qu.Catch()
 	if r.Method() == "POST" {
@@ -89,3 +170,20 @@ func (r *TagRule) TagImport() {
 		})
 	}
 }
+
+func (r *TagRule) TagSetup() {
+	defer qu.Catch()
+	if r.Method() == "POST" {
+		_id := r.GetString("_id")
+		i_isuse := r.GetString("i_isuse")
+		set := bson.M{
+			"$set": bson.M{
+				"i_isuse": i_isuse,
+			},
+		}
+		b := Mgo.UpdateById("tagrule", _id, set)
+		r.ServeJson(map[string]interface{}{
+			"rep": b,
+		})
+	}
+}

+ 6 - 1
src/util/config.go

@@ -27,6 +27,7 @@ var (
 	MatchTypeMap2 map[string]interface{}    //匹配方式
 	ExistFiled    []string                  //存在的字段
 	ScopeClassMap *[]map[string]interface{} //公告行业
+	TagFieldMap   *[]map[string]interface{}	//标签属性值
 	TaskTypeMap   *[]map[string]interface{} //任务类型
 )
 
@@ -60,6 +61,7 @@ func InitOther() {
 	initMgoEn()
 	Subday = qu.Float64All(Sysconfig["subday"])
 	PreviewHref = qu.ObjToString(Sysconfig["preview_href"])
+	initTagField()
 }
 
 func initCitys() {
@@ -137,8 +139,11 @@ func initTaskType() {
 	TaskTypeMap, _ = Mgo.Find("code_task", `{}`, `{"_id": 1}`, `{}`, false, -1, -1)
 }
 
-
 func initEs() {
 	EsIndex, EsType = qu.ObjToString(Sysconfig["elasticsearch_index"]), qu.ObjToString(Sysconfig["elasticsearch_type"])
 	elastic.InitElasticSize(qu.ObjToString(Sysconfig["elasticsearch"]), qu.IntAllDef(qu.Int64All(Sysconfig["elasticPoolSize"]), 30))
 }
+
+func initTagField()  {
+	TagFieldMap, _ = Mgo.Find("code_tagfield", `{}`, `{"_id": 1}`, `{}`, false, -1, -1)
+}

+ 44 - 23
src/util/utiltag.go

@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"log"
 	"models"
 	"qfw/util"
 	"qfw/util/elastic"
@@ -105,46 +104,68 @@ func UtilEsFind(tags map[string]interface{}) (error, int64) {
 				item["s_jyhref"] = fmt.Sprintf(Url, util.CommonEncodeArticle("content", v.Id))
 				item["i_createtime"] = time.Now().Unix()
 				var d *DFA = &DFA{}
+				var analyKeys []string		 //找到的关键词
+				var matchType []string		 //匹配方式
 				for _, math := range maths {
 					fileds := strsToArr(math["s_keymatch"], "field")
 					d.AddWord(strings.Split(math["s_matchkey"], ",")...)
 					mkMap := make(map[string]interface{})
+					tmpMap := make(map[string]interface{})
 					for _, mk := range strings.Split(math["s_matchkey"], ",") {
-						if b, _ := regexp.MatchString("[A-Z]", mk); b {
-							mkMap[strings.ToLower(mk)] = mk
-							d.AddWord(strings.ToLower(mk))
+						if strings.Contains(mk, "&&") {
+							arr := strings.Split(mk, "&&")
+							for _, s := range arr{
+								if s != "" {
+									tmpMap[s] = mk
+									if b, _ := regexp.MatchString("[A-Z]", s); b {
+										mkMap[strings.ToLower(s)] = s
+										d.AddWord(strings.ToLower(s))
+									}else {
+										d.AddWord(mk)
+									}
+								}
+							}
+						}else {
+							if b, _ := regexp.MatchString("[A-Z]", mk); b {
+								mkMap[strings.ToLower(mk)] = mk
+								d.AddWord(strings.ToLower(mk))
+							}else {
+								d.AddWord(mk)
+							}
 						}
 					}
-					analyKeys := []string{}
 					for _, filed := range fileds {
 						filed1 := strings.ToLower(util.ObjToString(item[filed]))
 						ddds := d.Analy(filed1)
 						analyKeys = append(analyKeys, ddds...)
 					}
 					if len(analyKeys) > 0 {
-						ssavekey := make(map[string]bool)
-						for _, v := range analyKeys {
-							ssavekey[v] = true
-						}
-						ssavekeys := []string{}
-						for k := range ssavekey {
-							ssavekeys = append(ssavekeys, k)
+						matchType = append(matchType, strings.Join(fileds, ","))
+						for k, v := range analyKeys{
+							if tmpMap[v] != "" && tmpMap[v] != nil {
+								analyKeys[k] = util.ObjToString(tmpMap[v])
+							}
 						}
-						for _, v1 := range ssavekeys{
+						for _, v1 := range analyKeys{
 							if mkMap[v1] != "" && mkMap[v1] != nil {
-								ssavekeys = deleteSlice(ssavekeys, v1)
-								ssavekeys = append(ssavekeys, util.ObjToString(mkMap[v1]))
+								analyKeys = deleteSlice(analyKeys, v1)
+								analyKeys = append(analyKeys, util.ObjToString(mkMap[v1]))
 							}
 						}
-						if len(ssavekeys) > 9 {
-							util.Debug(ssavekeys)
-						}
-						item["s_matchkey"] = strings.Join(ssavekeys, ",")
-						item["s_matchtype"] = strings.Join(fileds, ",")
-						break
 					}
+					d.Clear()
+				}
+				//去重
+				ssavekey := make(map[string]bool)
+				for _, v := range analyKeys {
+					ssavekey[v] = true
+				}
+				ssavekeys := []string{}
+				for k := range ssavekey {
+					ssavekeys = append(ssavekeys, k)
 				}
-				d.Clear()
+				item["s_matchkey"] = strings.Join(ssavekeys, ",")
+				item["s_matchtype"] = strings.Join(matchType, ",")
 				findwinner := strings.TrimSpace(util.ObjToString(item["winner"]))
 				if findwinner != "" {
 					finddata, _ := MgoEn.FindOne(MgoEnC, bson.M{"company_name": findwinner})
@@ -165,7 +186,7 @@ func UtilEsFind(tags map[string]interface{}) (error, int64) {
 		count := searchResult.Hits.TotalHits
 		return UtilEsSaveData(sdataid, &datas), count
 	} else {
-		log.Println("es:", err)
+		util.Debug(err)
 		return err, 0
 	}
 }

+ 18 - 0
src/web/res/js/com.js

@@ -149,4 +149,22 @@ com.getCookie = function (c_name){
 		}
 	}
 	return ""
+}
+function deleteArrayVal(arrTobeDel, indexItem) {
+	//索引集合里面必须全部为‘number’
+	for (var i = 0; i < indexItem.length; ++i) {
+		if (typeof indexItem[i] != 'number') throw new TypeError(`index is not a number`);
+	}
+
+	//避免后面的操作改变传入数组的值
+	var newArrItem = JSON.parse(JSON.stringify(arrTobeDel)),
+		newIndexItem = JSON.parse(JSON.stringify(indexItem));
+	//将传入的数组按照倒序排列
+	newIndexItem.sort((a, b) => b - a);
+
+	for (var j = 0; j < newIndexItem.length; j++) {
+		newArrItem.splice(newIndexItem[j], 1);
+	}
+
+	return newArrItem;
 }

+ 46 - 0
src/web/res/other/css/other.css

@@ -61,4 +61,50 @@
   padding-left: 10px;
   cursor: pointer;
   background: #d2d6de;
+}
+.edit-form {
+  margin: 16px;
+}
+
+.edit-info {
+  font-size: 20px;
+  margin-bottom: 14px;
+  margin-top: -21px;
+  font-weight: 600;
+  border-bottom: 1px solid #e2d9d9;
+  margin-left: -30px;
+  height: 33px;
+}
+
+.btn_content {
+  white-space: nowrap;
+  overflow-x: scroll;
+  -webkit-overflow-scrolling: touch;
+}
+
+.btn-group-top {
+  width: 100%;
+  padding-bottom: 5px;
+  height: 40px;
+  border-bottom: 1px solid #e2d9d9;
+}
+
+.btn-group-sub {
+  float: left;
+  padding-bottom: 20px;
+}
+
+.btn_top {
+  width: 120px;
+!important;
+  margin-right: 5px;
+  background-color: #F5F5F5;
+}
+
+.btn-sub {
+  width: 120px;
+!important;
+  margin-top: 3px;
+  margin-right: 5px;
+  display: inherit;
 }

+ 6 - 55
src/web/templates/com/modal.html

@@ -8,7 +8,7 @@
                     <div class="edit-form">
                         <div class="edit-info">
                             <span class="glyphicon glyphicon-import" aria-hidden="true"></span>
-                            <span class="info">导入ES语句</span>
+                            <span class="edit-info">导入ES语句</span>
                         </div>
                         <div class="col-sm-12">
                             <textarea class="form-control" id="es_json" placeholder="请输入ES语句"></textarea>
@@ -35,7 +35,7 @@
                     <div class="edit-form">
                         <div class="edit-info">
                             <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
-                            <span class="info">匹配方式</span>
+                            <span class="edit-info">匹配方式</span>
                         </div>
                         <div id="btnGroupMatch"></div>
                         <div id="btnGroupMatch2" style="margin-top: 15px"></div>
@@ -61,7 +61,7 @@
                     <div class="edit-form">
                         <div class="edit-info">
                             <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
-                            <span class="info">采购单位行业</span>
+                            <span class="edit-info">采购单位行业</span>
                         </div>
                         <div id="btnGroupBuyer"></div>
                     </div>
@@ -86,7 +86,7 @@
                     <div class="edit-form">
                         <div class="edit-info">
                             <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
-                            <span class="info">公告行业</span>
+                            <span class="edit-info">公告行业</span>
                         </div>
                         <div class="btn_content">
                             <div id="btnGroupTop" class="btn-group-top"></div>
@@ -115,7 +115,7 @@
                     <div class="edit-form">
                         <div class="edit-info">
                             <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
-                            <span class="info">数据预览</span>
+                            <span class="edit-info">数据预览</span>
                         </div>
                         <div class="btn_content">
                             <div style="text-align: right">
@@ -175,7 +175,7 @@
                     <div class="edit-form">
                         <div class="edit-info">
                             <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
-                            <span class="info">新增关键词</span>
+                            <span class="edit-info">新增关键词</span>
                         </div>
                         <form class="form-horizontal">
                             <div class="form-group">
@@ -209,55 +209,6 @@
     </div><!-- /.modal -->
 </div>
 
-<style>
-    .edit-form {
-        margin: 16px;
-    }
-
-    .edit-info {
-        font-size: 20px;
-        margin-bottom: 14px;
-        margin-top: -21px;
-        font-weight: 600;
-        border-bottom: 1px solid #e2d9d9;
-        margin-left: -30px;
-        height: 33px;
-    }
-
-    .btn_content {
-        white-space: nowrap;
-        overflow-x: scroll;
-        -webkit-overflow-scrolling: touch;
-    }
-
-    .btn-group-top {
-        width: 100%;
-        padding-bottom: 5px;
-        height: 40px;
-        border-bottom: 1px solid #e2d9d9;
-    }
-
-    .btn-group-sub {
-        float: left;
-        padding-bottom: 20px;
-    }
-
-    .btn_top {
-        width: 120px;
-    !important;
-        margin-right: 5px;
-        background-color: #F5F5F5;
-    }
-
-    .btn-sub {
-        width: 120px;
-    !important;
-        margin-top: 3px;
-        margin-right: 5px;
-        display: inherit;
-    }
-</style>
-
 <!-- 通用标签modal -->
 <div class="modal fade" id="modal-comrule" tabindex="-1" role="dialog" aria-hidden="true">
     <div class="modal-dialog" style="width: 80%">

+ 5 - 6
src/web/templates/private/common_rule_create.html

@@ -1375,15 +1375,14 @@
     }
     //关键词删除
     function del_Rule() {
-        if (keyTableChecked) {
+        if (keyTableChecked && selectIndex.length > 0) {
             showConfirm("确定删除?", function() {
-                for (var i in o_rules) {
+                var tmp = []
+                for (var i in selectIndex) {
                     var j = selectIndex[i] - 1;
-                    if (i != j) {
-                        tmp.push(o_rules[i])
-                    }
+                    tmp.push(j)
                 }
-                o_rules = tmp;
+                o_rules = deleteArrayVal(o_rules, tmp)
                 $('#keywords').dataTable().fnClearTable();
                 $('#keywords').dataTable().fnAddData(o_rules);
 

+ 5 - 23
src/web/templates/private/common_rule_edit.html

@@ -763,23 +763,6 @@
             matchCode.length = 0;
             matchName.length = 0;
             $('#modal-select-match').modal("show");
-            if (setValue == 0) {
-                $('#btnGroupMatch').find('input').each(function () {
-                    if (dataMap.s_globaladdkeymatch.indexOf($(this).attr("code")) > -1) {
-                        $(this).addClass("active-btn-match");
-                        matchName.push($(this).attr("value"));
-                        matchCode.push($(this).attr("code"))
-                    }
-                })
-            }else {
-                $('#btnGroupMatch').find('input').each(function () {
-                    if (dataMap.s_globalnotkeymatch.indexOf($(this).attr("code")) > -1) {
-                        $(this).addClass("active-btn-match");
-                        matchName.push($(this).attr("value"));
-                        matchCode.push($(this).attr("code"))
-                    }
-                })
-            }
         }else {
             if (selectIndex.length > 0 && keyTableChecked) {
                 matchCode.length = 0;
@@ -1535,15 +1518,14 @@
     }
     //关键词删除
     function del_Rule() {
-        if (keyTableChecked) {
+        if (keyTableChecked && selectIndex.length > 0) {
             showConfirm("确定删除?", function() {
-                for (var i in o_rules) {
+                var tmp = []
+                for (var i in selectIndex) {
                     var j = selectIndex[i] - 1;
-                    if (i != j) {
-                        tmp.push(o_rules[i])
-                    }
+                    tmp.push(j)
                 }
-                o_rules = tmp;
+                o_rules = deleteArrayVal(o_rules, tmp)
                 $('#keywords').dataTable().fnClearTable();
                 $('#keywords').dataTable().fnAddData(o_rules);
 

+ 11 - 6
src/web/templates/private/rule_create.html

@@ -647,6 +647,9 @@
         $('#btnGroupMatch').find("input").each(function () {
             $(this).removeClass("active-btn-match");
         });
+        $('#btnGroupMatch2').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
         $('#btnGroupBuyer').find("input").each(function () {
             $(this).removeClass("active-btn-match");
         });
@@ -736,6 +739,9 @@
         $('#btnGroupMatch').find("input").each(function () {
             $(this).removeClass("active-btn-match");
         });
+        $('#btnGroupMatch2').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
         var matchNameStr = "";
         var codeStr = "";
         for (var i in matchName) {
@@ -1466,15 +1472,14 @@
     }
     //关键词删除
     function del_Rule() {
-        if (keyTableChecked) {
+        if (keyTableChecked && selectIndex.length > 0) {
             showConfirm("确定删除?", function() {
-                for (var i in o_rules) {
+                var tmp = []
+                for (var i in selectIndex) {
                     var j = selectIndex[i] - 1;
-                    if (i != j) {
-                        tmp.push(o_rules[i])
-                    }
+                    tmp.push(j)
                 }
-                o_rules = tmp;
+                o_rules = deleteArrayVal(o_rules, tmp)
                 $('#keywords').dataTable().fnClearTable();
                 $('#keywords').dataTable().fnAddData(o_rules);
 

+ 11 - 25
src/web/templates/private/rule_edit.html

@@ -757,6 +757,9 @@
         $('#btnGroupMatch').find("input").each(function () {
             $(this).removeClass("active-btn-match");
         });
+        $('#btnGroupMatch2').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
         $('#btnGroupBuyer').find("input").each(function () {
             $(this).removeClass("active-btn-match");
         });
@@ -815,24 +818,6 @@
             matchCode.length = 0;
             matchName.length = 0;
             $('#modal-select-match').modal("show");
-
-            if (setValue == 0) {
-                $('#btnGroupMatch').find('input').each(function () {
-                    if (dataMap.s_globaladdkeymatch.indexOf($(this).attr("code")) > -1) {
-                        $(this).addClass("active-btn-match");
-                        matchName.push($(this).attr("value"));
-                        matchCode.push($(this).attr("code"))
-                    }
-                })
-            }else {
-                $('#btnGroupMatch').find('input').each(function () {
-                    if (dataMap.s_globalnotkeymatch.indexOf($(this).attr("code")) > -1) {
-                        $(this).addClass("active-btn-match");
-                        matchName.push($(this).attr("value"));
-                        matchCode.push($(this).attr("code"))
-                    }
-                })
-            }
         }else {
             if (selectIndex.length > 0 && keyTableChecked) {
                 matchCode.length = 0;
@@ -886,6 +871,9 @@
         $('#btnGroupMatch').find("input").each(function () {
             $(this).removeClass("active-btn-match");
         });
+        $('#btnGroupMatch2').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
         $('#modal-select-match').modal("hide");
         var matchNameStr = "";
         var codeStr = "";
@@ -1627,16 +1615,14 @@
     //关键词删除
     function del_Rule() {
         console.log(selectIndex);
-        if (keyTableChecked) {
-            var tmp = [];
+        if (keyTableChecked && selectIndex.length > 0) {
             showConfirm("确定删除?", function() {
-                for (var i in o_rules) {
+                var tmp = []
+                for (var i in selectIndex) {
                     var j = selectIndex[i] - 1;
-                    if (i != j) {
-                        tmp.push(o_rules[i])
-                    }
+                    tmp.push(j)
                 }
-                o_rules = tmp;
+                o_rules = deleteArrayVal(o_rules, tmp)
                 $('#keywords').dataTable().fnClearTable();
                 $('#keywords').dataTable().fnAddData(o_rules);
 

+ 362 - 13
src/web/templates/private/tag_rule_create.html

@@ -3,8 +3,6 @@
 {{include "com/header.html"}}
 <!-- Left side column. 权限菜单 -->
 {{include "com/menu.html"}}
-<script src="/time/js/angular.min.js"></script>
-<script src="/time/js/wui-date.js"></script>
 <div class="content-wrapper">
     <section class="content-header">
         <h1>新建标签规则
@@ -28,6 +26,7 @@
                 <ul class="nav nav-tabs edit-step">
                     <li class="active" data-mode="guide"><a href="#tab_1" data-toggle="tab" aria-expanded="true">通用规则</a></li>
                     <li data-mode="guide" class=""><a href="#tab_2" data-toggle="tab" aria-expanded="false">关键词规则</a></li>
+                    <button class="btn btn-primary btn-sm" style="float: right;margin-top: 7px;margin-right: 10px" onclick="saveTag()"><i class="fa fa-fw fa-file-text fa-lg"></i>保存规则标签</button>
                 </ul>
                 <div class="tab-content">
                     <div class="tab-pane active" id="tab_1">
@@ -41,37 +40,49 @@
                                     <div class="form-group">
                                         <label class="col-sm-2 control-label"><span style="color:red;">* </span>标签规则名称</label>
                                         <div class="col-sm-3">
-                                            <input type="text" class="form-control" id="customer" placeholder="标签规则名称" required>
+                                            <input type="text" class="form-control" id="tagname" placeholder="标签规则名称" required>
                                         </div>
                                     </div>
                                     <div class="form-group">
                                         <label class="col-sm-2 control-label"><span style="color:red;">* </span>属性值</label>
                                         <div class="col-sm-3">
                                             <select class="form-control selectpicker" id="fieldSelect">
-                                                <option selected:disabled style="diaplay:none" value=0>请选择</option>
+                                                <option selected:disabled style="diaplay:none" value="0">请选择</option>
                                             </select>
                                         </div>
+                                        <script>
+                                            $('#fieldSelect').on('changed.bs.select', function () {
+                                                const tmp = "pre_" + $(this).val();
+                                                $('#pretagfield').val(tmp)
+                                            })
+                                        </script>
                                     </div>
                                     <div class="form-group">
                                         <label class="col-sm-2 control-label"><span style="color:red;">* </span>任务类型</label>
                                         <div class="col-sm-3">
                                             <select class="form-control selectpicker" id="taskSelect">
-                                                <option selected:disabled style="diaplay:none" value=0>请选择</option>
+                                                <option selected:disabled style="diaplay:none" value="0">请选择</option>
                                             </select>
                                         </div>
                                     </div>
                                     <div class="form-group">
                                         <label class="col-sm-2 control-label">父标签名称</label>
                                         <div class="col-sm-3">
-                                            <input type="text" class="form-control" id="customername" placeholder="父标签名称"
+                                            <input type="text" class="form-control" id="pretagname" placeholder="父标签名称"
                                                    value="">
                                         </div>
                                         <label class="col-sm-2 control-label">父标签属性值</label>
                                         <div class="col-sm-3">
-                                            <input type="text" class="form-control" disabled id="parent" placeholder="父标签属性值"
+                                            <input type="text" class="form-control" disabled id="pretagfield" placeholder="父标签属性值"
                                                    value="">
                                         </div>
                                     </div>
+                                    <div id="es_div" class="form-group">
+                                        <label class="col-sm-2 control-label">查询条件</label>
+                                        <div class="col-sm-8">
+                                            <textarea class="form-control" id="query" style="max-width: 100%"></textarea>
+                                        </div>
+                                    </div>
                                 </div>
                             </div>
                         </form>
@@ -111,12 +122,118 @@
     </section>
 </div>
 
+<!-- 新增关键词规则模态框 -->
+<div class="modal fade" id="modal-add-keyword" tabindex="-1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog" style="width: 60%">
+        <div class="modal-content">
+            <div class="modal-header">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+                    <div class="edit-form">
+                        <div class="edit-info">
+                            <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
+                            <span class="edit-info">新增关键词</span>
+                        </div>
+                        <form class="form-horizontal">
+                            <div class="form-group">
+                                <label class="col-sm-2 control-label"><span style="color:red;">* </span>关键词</label>
+                                <div class="col-sm-10">
+                                    <textarea class="form-control" style="max-width: 100%" placeholder="输入关键词"
+                                              id="keyword_txt"></textarea></div>
+                            </div>
+                            <div class="form-group">
+                                <label class="col-sm-2 control-label">附加词</label>
+                                <div class="col-sm-10">
+                                    <textarea class="form-control" style="max-width: 100%" placeholder="输入附件词"
+                                              id="addword_txt"></textarea></div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <input type="button" onclick="saveKeyword()" class="btn btn-primary saveBtn" value="保存">
+                    <input type="button" onclick="cancelModel()" class="btn btn-default" style="margin-left: 24px"
+                           value="取消">
+                </div>
+            </div>
+        </div>
+    </div><!-- /.modal -->
+</div>
+<!-- 选择匹配方式模态框 -->
+<div class="modal fade" id="modal-select-match" tabindex="-1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog" style="width: 50%">
+        <div class="modal-content">
+            <div class="modal-header">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+                    <div class="edit-form">
+                        <div class="edit-info">
+                            <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
+                            <span class="edit-info">匹配方式</span>
+                        </div>
+                        <div id="btnGroupMatch"></div>
+                        <div id="btnGroupMatch2" style="margin-top: 15px"></div>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <input type="button" onclick="saveMatch()" class="btn btn-primary saveBtn" value="保存">
+                    <input type="button" onclick="cancelModel()" class="btn btn-default" style="margin-left: 24px"
+                           value="取消">
+                </div>
+            </div>
+        </div>
+    </div><!-- /.modal -->
+</div>
 {{include "com/dialog.html"}}
 {{include "com/footer.html"}}
 <script>
-    menuActive("/service/rule/list");
+    menuActive("/tag_rule/list");
+    var TagFieldMap = {{.T.tagFieldMap}}
+    var TaskTypeMap = {{.T.taskTypeMap}}
+    var matchTypeMap = {{.T.matchTypeMap}};
+
+    var keyTableChecked = false;        //关键词表格数据是否有选中
+    var keyTableAllChecked = true;      //表单数据是否被全选中
+
+    var setValue = 0;                   // 4: 关键词匹配方式,6:附加词匹配方式
+    var selectIndex = [];               //选中的编号
+    var o_list = [];
+    var matchCode = [];     //匹配方式code
+    var matchName = [];     //匹配名字
+
+    //表单数据
+    var dataMap = {
+        "s_tagname": "",
+        "s_tagfield": "",
+        "s_tasktype": ""
+    };
 
     $(document).ready(function () {
+        for (var i in TagFieldMap) {
+            var provOpt = document.createElement('option');
+            provOpt.innerText = TagFieldMap[i].name;
+            provOpt.value = TagFieldMap[i].code;
+            $("#fieldSelect")[0].appendChild(provOpt);
+        }
+        for (var i in TaskTypeMap) {
+            var provOpt = document.createElement('option');
+            provOpt.innerText = TaskTypeMap[i].name;
+            provOpt.value = TaskTypeMap[i].code;
+            $("#taskSelect")[0].appendChild(provOpt);
+        }
+        var btnMatchHtml1 = "";
+        var btnMatchHtml2 = "";
+        for (var i in matchTypeMap) {
+            if (i < 5) {
+                btnMatchHtml1 += `<input type="button" class="btn btn-default col-md-pull-2" style="margin-left: 10px;margin-top: 10px" onclick="clickMatchBtn(this)"
+                            code="${matchTypeMap[i]["code"]}" value="${matchTypeMap[i]["name"]}">`;
+            }else {
+                btnMatchHtml2 += `<input type="button" class="btn btn-default col-md-pull-2" style="margin-left: 10px;margin-top: 10px" onclick="clickMatchBtn2(this)"
+                            code="${matchTypeMap[i]["code"]}" value="${matchTypeMap[i]["name"]}">`;
+            }
+        }
+        $("#btnGroupMatch").append(btnMatchHtml1);
+        $("#btnGroupMatch2").append(btnMatchHtml2);
         $('#keywords').DataTable({
             "paging": false,
             "lengthChange": false,
@@ -199,7 +316,16 @@
             }]
         });
     })
-
+    function cancelModel() {
+        $('#modal-add-keyword').modal("hide");
+        $('#modal-select-match').modal("hide");
+        $('#btnGroupMatch').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+        $('#btnGroupMatch2').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+    }
     function importRule() {
         $("#file").click();
     }
@@ -221,7 +347,9 @@
                     processData: false,// 使数据不做处理
                     success: function (r) {
                         if (r.rep) {
-                            addkeyWord(r.rdata);
+                            o_list = r.rdata["o_rules"]
+                            $('#keywords').dataTable().fnClearTable();
+                            $('#keywords').dataTable().fnAddData(o_list);
                             showTip("导入成功",1000);
                         } else {
                             showTip("导入失败",1000);
@@ -231,10 +359,231 @@
             }
         })
     });
-    function addkeyWord(rdata) {
+    function allSelect(obj) {
+        if ($(obj).is(':checked')) {
+            keyTableChecked = true;
+            keyTableAllChecked = true;
+            $('input[name="ckb-keyid"]').each(function () {
+                this.checked = true;
+                selectIndex.push($(this).parents("tr").index() + 1);
+            })
+        }else {
+            selectIndex.length = 0;
+            keyTableChecked = false;
+            keyTableAllChecked = false;
+            $('input[name="ckb-keyid"]').each(function () {
+                this.checked = false;
+            })
+        }
+    }
+    function singleSelect(obj) {
+        var tag = true;
+        selectIndex.length = 0;
+        $('input[name="ckb-keyid"]').each(function () {
+            if (this.checked) {
+                keyTableChecked = true;
+                selectIndex.push($(this).parents("tr").index() + 1);
+            }else {
+                tag = false
+            }
+        });
+        if (tag) {
+            keyTableAllChecked = true;
+            $('#allCheckbox').prop("checked", true);
+        }else {
+            keyTableAllChecked = false;
+            $('#allCheckbox').prop("checked", false);
+        }
+    }
+    function saveTag() {
+        dataMap.s_tagname = $('#tagname').val()
+        dataMap.s_pretagname = $('#pretagname').val()
+        dataMap.s_tagfield = $('#fieldSelect').val()
+        dataMap.s_tasktype = $('#taskSelect').val()
+        dataMap.s_query = $('#query').val()
+        if (dataMap.s_tagname == "" || dataMap.s_tagfield == "" || dataMap.s_tasktype == "") {
+            alert("请填写必须字段!")
+            return
+        }
+        if (o_list.length > 0) {
+            for (const i in o_list) {
+                if (o_list[i].s_matchkey && !o_list[i].s_keymatch) {
+                    showMsg("保存失败,关键词规则中有关键词未对应匹配方式!")
+                    return;
+                }
+                if (o_list[i].s_addkey && !o_list[i].s_addkeymatch) {
+                    showMsg("保存失败,关键词规则中有附加词未对应匹配方式!")
+                    return;
+                }
+            }
+        }
+        dataMap["o_list"] = JSON.stringify(o_list);
+        $.ajax({
+            url: "/service/tag_rule/save",
+            type: 'POST',
+            data: dataMap,
+            success: function (r) {
+                if (r.rep && r.id) {
+                    dataMap["id"]= r.id;
+                    showTip("保存成功", 1000);
+                } else {
+                    showTip("保存失败", 1000);
+                }
+            }
+        })
+    }
+    function selectKeyMatch(val) {
+        setValue = val
+        if (selectIndex.length > 0 && keyTableChecked) {
+            matchCode.length = 0;
+            matchName.length = 0;
+            $('#modal-select-match').modal("show");
+        }else {
+            alert("请选中关键词")
+        }
+    }
+    //匹配方式按钮点击事件
+    function clickMatchBtn(obj) {
+        if ($(obj).hasClass("active-btn-match")) {
+            $(obj).removeClass("active-btn-match")
+            matchCode.splice($.inArray($(obj).attr("code"), matchCode), 1);
+            matchName.splice($.inArray($(obj).val(), matchName), 1)
+        } else {
+            $(obj).addClass("active-btn-match");
+            matchCode.push($(obj).attr("code"));
+            matchName.push($(obj).val())
+        }
+
+        $('#btnGroupMatch2 .btn-default').each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+    }
+    function clickMatchBtn2(obj) {
+        matchCode.length = 0;
+        matchName.length = 0;
+        if ($(obj).hasClass("active-btn-match")) {
+            $(obj).removeClass("active-btn-match")
+            matchCode.splice($.inArray($(obj).attr("code"), matchCode), 1);
+            matchName.splice($.inArray($(obj).val(), matchName), 1)
+        } else {
+            $(obj).addClass("active-btn-match");
+            matchCode.push($(obj).attr("code"));
+            matchName.push($(obj).val())
+            $('#btnGroupMatch2 .btn-default').each(function () {
+                if (this != obj) {
+                    $(this).removeClass("active-btn-match");
+                }
+            });
+        }
+
+        $('#btnGroupMatch .btn-default').each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+    }
+    //匹配方式保存
+    function saveMatch() {
+        $('#btnGroupMatch').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+        $('#btnGroupMatch2').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+        var matchNameStr = "";
+        var codeStr = "";
+        for (var i in matchName) {
+            if (matchNameStr == "") {
+                matchNameStr = matchName[i];
+            }else {
+                matchNameStr += "," + matchName[i]
+            }
+            if (codeStr == "") {
+                codeStr = matchCode[i]
+            }else {
+                codeStr = codeStr + "," + matchCode[i]
+            }
+        }
+        for (var i in selectIndex) {
+            var j = selectIndex[i] - 1;
+            if (setValue == 4) {
+                if ($("#keywords tbody tr:nth-child("+selectIndex[i]+") td:nth-child(3)").text() != "") {
+                    $("#keywords tbody tr:nth-child("+selectIndex[i]+") td:nth-child("+setValue+")").html(matchNameStr);
+                    o_list[j]["s_keymatch"] = codeStr;
+                }
+            }else if (setValue == 6) {
+                if ($("#keywords tbody tr:nth-child("+selectIndex[i]+") td:nth-child(5)").text() != "") {
+                    $("#keywords tbody tr:nth-child("+selectIndex[i]+") td:nth-child("+setValue+")").html(matchNameStr);
+                    o_list[j]["s_addkeymatch"] = codeStr;
+                }
+            }
+        }
+        $('#modal-select-match').modal("hide");
+        matchName.length = 0;
+        matchCode.length = 0;
+    }
+    var key_flag = -1;      // 0:新增,1:修改
+    //关键词表格新增
+    function add_Rule() {
+        key_flag = 0;
+        $('#keyword_txt').val("");
+        $('#addword_txt').val("");
+        $('#notword_txt').val("");
+        $('#modal-add-keyword').modal("show");
+    }
+    //关键词修改
+    function modify_Rule(){
+        if (selectIndex.length == 1) {
+            key_flag = 1;
+            var index = selectIndex[0] - 1;
+            $('#modal-add-keyword').modal("show");
+            $('#keyword_txt').val(o_rules[index].s_matchkey);
+            $('#addword_txt').val(o_rules[index].s_addkey);
+            $('#notword_txt').val(o_rules[index].s_notkey);
+        }else {
+            showTip("请选中需要修改的关键词,且只能选中一条", 1000)
+        }
 
-        $('#keywords').dataTable().fnClearTable();
-        $('#keywords').dataTable().fnAddData(rdata["o_rules"]);
+    }
+    function saveKeyword() {
+        var key = $('#keyword_txt').val();
+        var addkey = $('#addword_txt').val();
+        if (key != "") {
+            var rule = {};
+            rule["s_matchkey"] = key.replace(",", ",");
+            if (addkey != "") rule["s_addkey"] = addkey.replace(",", ",");
+            $('#modal-add-keyword').modal('hide');
+            if (key_flag == 1) {
+                var index = selectIndex[0] - 1;
+                o_rules.splice(index, 1, rule)
+            }else {
+                o_rules.push(rule)
+            }
+            $('#keywords').dataTable().fnClearTable();
+            $('#keywords').dataTable().fnAddData(o_rules);
+        }else {
+            showTip("关键词不能为空", 500)
+        }
+    }
+    //关键词删除
+    function del_Rule() {
+        if (keyTableChecked && selectIndex.length > 0) {
+            showConfirm("确定删除?", function() {
+                var tmp = []
+                for (var i in selectIndex) {
+                    var j = selectIndex[i] - 1;
+                    tmp.push(j)
+                }
+                o_list = deleteArrayVal(o_list, tmp)
+                $('#keywords').dataTable().fnClearTable();
+                $('#keywords').dataTable().fnAddData(o_list);
 
+                keyTableChecked = false;
+                if (o_list.length == 0) {
+                    $('#allCheckbox').prop("checked", false);
+                    $('#keywords').dataTable().fnClearTable();
+                }
+            })
+        }else {
+            showTip("请选中需要删除的关键词", 500)
+        }
     }
 </script>

+ 462 - 0
src/web/templates/private/tag_rule_edit.html

@@ -0,0 +1,462 @@
+{{include "com/inc.html"}}
+<!-- Main Header -->
+{{include "com/header.html"}}
+<!-- Left side column. 权限菜单 -->
+{{include "com/menu.html"}}
+{{include "com/modal.html"}}
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1>新建标签规则
+            <small>
+                <button class="btn btn-primary btn-sm" onclick="importRule()"><i class="fa fa-fw fa-cloud-upload fa-lg"></i>导入关键词</button>
+                <form style="display:none" id='uploadform' method='post'>
+                    <input type='file' name='xlsx' id='file'/>
+                </form>
+            </small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="#"><i class="fa fa-dashboard"></i> 首页</a></li>
+            <li><a href="/service/rule/list">标签规则列表</a></li>
+            <li><a href="#">新建标签规则</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="tab-content">
+            <div class="nav-tabs-custom">
+                <ul class="nav nav-tabs edit-step">
+                    <li class="active" data-mode="guide"><a href="#tab_1" data-toggle="tab" aria-expanded="true">通用规则</a></li>
+                    <li data-mode="guide" class=""><a href="#tab_2" data-toggle="tab" aria-expanded="false">关键词规则</a></li>
+                    <button class="btn btn-primary btn-sm" style="float: right;margin-top: 7px;margin-right: 10px" onclick="saveTag()"><i class="fa fa-fw fa-file-text fa-lg"></i>保存规则标签</button>
+                </ul>
+                <div class="tab-content">
+                    <div class="tab-pane active" id="tab_1">
+                        <form class="form-horizontal">
+                            <div class="box box-primary">
+                                <div class="box-header with-border">
+                                    <i class="fa fa-tag"></i>
+                                    <h3 class="box-title">通用规则</h3>
+                                </div>
+                                <div class="box-body">
+                                    <div class="form-group">
+                                        <label class="col-sm-2 control-label"><span style="color:red;">* </span>标签规则名称</label>
+                                        <div class="col-sm-3">
+                                            <input type="text" class="form-control" id="tagname" placeholder="标签规则名称" required
+                                                   value="{{.T.data.s_tagname}}">
+                                        </div>
+                                    </div>
+                                    <div class="form-group">
+                                        <label class="col-sm-2 control-label"><span style="color:red;">* </span>属性值</label>
+                                        <div class="col-sm-3">
+                                            <select class="form-control selectpicker" id="fieldSelect">
+                                                <option selected:disabled style="diaplay:none" value="0">请选择</option>
+                                            </select>
+                                        </div>
+                                        <script>
+                                            $('#fieldSelect').on('changed.bs.select', function () {
+                                                const tmp = "pre_" + $(this).val();
+                                                $('#pretagfield').val(tmp)
+                                            })
+                                        </script>
+                                    </div>
+                                    <div class="form-group">
+                                        <label class="col-sm-2 control-label"><span style="color:red;">* </span>任务类型</label>
+                                        <div class="col-sm-3">
+                                            <select class="form-control selectpicker" id="taskSelect">
+                                                <option selected:disabled style="diaplay:none" value="0">请选择</option>
+                                            </select>
+                                        </div>
+                                    </div>
+                                    <div class="form-group">
+                                        <label class="col-sm-2 control-label">父标签名称</label>
+                                        <div class="col-sm-3">
+                                            <input type="text" class="form-control" id="pretagname" placeholder="父标签名称"
+                                                   value="{{.T.data.s_pretagname}}">
+                                        </div>
+                                        <label class="col-sm-2 control-label">父标签属性值</label>
+                                        <div class="col-sm-3">
+                                            <input type="text" class="form-control" disabled id="pretagfield" placeholder="父标签属性值"
+                                                   value="{{.T.data.s_pretagfield}}">
+                                        </div>
+                                    </div>
+                                    <div id="es_div" class="form-group">
+                                        <label class="col-sm-2 control-label">查询条件</label>
+                                        <div class="col-sm-8">
+                                            <textarea class="form-control" id="query" style="max-width: 100%"></textarea>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="tab-pane" id="tab_2">
+                        <div class="box box-primary">
+                            <div class="box-header with-border">
+                                <i class="fa fa-bookmark"></i>
+                                <h3 class="box-title">关键词规则</h3>
+                                <div style="float: right">
+                                    <a class="btn btn-default btn-sm" onclick="selectKeyMatch(4)">关键词匹配方式</a>
+                                    <a class="btn btn-default btn-sm" onclick="selectKeyMatch(6)">附加词匹配方式</a>
+                                </div>
+                            </div>
+                            <table id="keywords" class="table table-bordered">
+                                <thead>
+                                <div style="margin: 10px 10px 0px;">
+                                    <a class="btn btn-twitter" onclick="add_Rule()">新增</a>
+                                    <a class="btn btn-twitter" onclick="modify_Rule()">修改</a>
+                                    <a class="btn btn-twitter" onclick="del_Rule()">删除</a>
+                                </div>
+                                <tr>
+                                    <th>编号</th>
+                                    <th><input type="checkbox" onclick="allSelect(this)" id="allCheckbox"></th>
+                                    <th>关键词</th>
+                                    <th>匹配方式</th>
+                                    <th>附加词</th>
+                                    <th>匹配方式</th>
+                                </tr>
+                                </thead>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+{{include "com/dialog.html"}}
+{{include "com/footer.html"}}
+<script>
+    menuActive("/tag_rule/list");
+    var dataMap = {{.T.data}};
+    var TagFieldMap = {{.T.tagFieldMap}}
+    var TaskTypeMap = {{.T.taskTypeMap}}
+    var matchTypeMap = {{.T.matchTypeMap}};
+
+    var keyTableChecked = false;        //关键词表格数据是否有选中
+    var keyTableAllChecked = true;      //表单数据是否被全选中
+
+    var setValue = 0;                   // 4: 关键词匹配方式,6:附加词匹配方式
+    var selectIndex = [];               //选中的编号
+    var o_list = [];
+    var matchCode = [];     //匹配方式code
+    var matchName = [];     //匹配名字
+
+    $(document).ready(function () {
+        $('#query').val(dataMap.s_query);
+        for (var i in TagFieldMap) {
+            var provOpt = document.createElement('option');
+            provOpt.innerText = TagFieldMap[i].name;
+            provOpt.value = TagFieldMap[i].code;
+            if (dataMap.s_tagfield == TagFieldMap[i].code) {
+                provOpt.selected = true
+            }
+            $("#fieldSelect")[0].appendChild(provOpt);
+        }
+        for (var i in TaskTypeMap) {
+            var provOpt = document.createElement('option');
+            provOpt.innerText = TaskTypeMap[i].name;
+            provOpt.value = TaskTypeMap[i].code;
+            if (dataMap.s_tasktype == TaskTypeMap[i].code) {
+                provOpt.selected = true
+            }
+            $("#taskSelect")[0].appendChild(provOpt);
+        }
+        var btnMatchHtml1 = "";
+        var btnMatchHtml2 = "";
+        for (var i in matchTypeMap) {
+            if (i < 5) {
+                btnMatchHtml1 += `<input type="button" class="btn btn-default col-md-pull-2" style="margin-left: 10px;margin-top: 10px" onclick="clickMatchBtn(this)"
+                            code="${matchTypeMap[i]["code"]}" value="${matchTypeMap[i]["name"]}">`;
+            }else {
+                btnMatchHtml2 += `<input type="button" class="btn btn-default col-md-pull-2" style="margin-left: 10px;margin-top: 10px" onclick="clickMatchBtn2(this)"
+                            code="${matchTypeMap[i]["code"]}" value="${matchTypeMap[i]["name"]}">`;
+            }
+        }
+        $("#btnGroupMatch").append(btnMatchHtml1);
+        $("#btnGroupMatch2").append(btnMatchHtml2);
+        $('#keywords').DataTable({
+            "paging": false,
+            "lengthChange": false,
+            "searching": false,
+            "ordering": false,
+            "info": true,
+            "autoWidth": false,
+            "language": {
+                "url": "/dist/js/dataTables.chinese.lang"
+            },
+            "fnDrawCallback": function () {
+                this.api().column(0).nodes().each(function (cell, i) {
+                    cell.innerHTML = i + 1;
+                });
+            },
+            "columns": [
+                {"data": null, width: "1%"},
+                {"data": "", width: "1%", render: function() {
+                        return `<input type="checkbox" name="ckb-keyid" onclick="singleSelect(this)" style="text-align: center">`
+                    }},
+                {"data": "s_matchkey", width: "10%"},
+                {"data": function (row) {
+                        var str = row.s_keymatch;
+                        if (str && str != "") {
+                            var s = "";
+                            for (var i in matchTypeMap) {
+                                if (str.indexOf(matchTypeMap[i]["code"]) != -1) {
+                                    if (s == "") {
+                                        s = matchTypeMap[i]["name"]
+                                    } else {
+                                        s = s + "," + matchTypeMap[i]["name"]
+                                    }
+                                }
+                            }
+                            return s
+                        }
+                        return ""
+                    }, width: "5%"},
+                {"data": "s_addkey", width: "10%"},
+                {"data": function (row) {
+                        var str = row.s_addkeymatch;
+                        if (str && str != "") {
+                            var s = "";
+                            for (var i in matchTypeMap) {
+                                if (str.indexOf(matchTypeMap[i]["code"]) != -1) {
+                                    if (s == "") {
+                                        s = matchTypeMap[i]["name"]
+                                    } else {
+                                        s = s + "," + matchTypeMap[i]["name"]
+                                    }
+                                }
+                            }
+                            return s
+                        }
+                        return ""
+                    }, width: "5%"},
+            ],
+            "columnDefs": [{
+                "targets": [2],
+                "render": function (data, type, full, meta) {
+                    if (data && data.length > 44) {
+                        return "<a title='" + data + "' href='#' style='text-decoration: none;'>" + data.trim().substr(0, 44) + "..." + "</a>";
+                    }else if (data == undefined) {
+                        return ""
+                    }else {
+                        return data
+                    }
+                }
+            }, {
+                "targets": [4],
+                "render": function (data, type, full, meta) {
+                    if (data && data.length > 44) {
+                        return "<a title='" + data + "' href='#' style='text-decoration: none;'>" + data.trim().substr(0, 44) + "..." + "</a>";
+                    }else if (data == undefined) {
+                        return ""
+                    }else {
+                        return data
+                    }
+                }
+            }]
+        });
+    })
+    function cancelModel() {
+        $('#modal-select-match').modal("hide");
+        $('#btnGroupMatch').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+        $('#btnGroupMatch2').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+    }
+    function importRule() {
+        $("#file").click();
+    }
+    $(function() {
+        $("#uploadform").find("input").change(function () {
+            var val = $(this).val() ? $(this).val() : "";
+            if (val.indexOf(".xlsx") < 0) {
+                showMsg("文件格式非法", function () {
+                });
+            } else {
+                var myform = new FormData();
+                myform.append('xlsx', $("#file")[0].files[0]);
+                $.ajax({
+                    url: "/service/tag_rule/import",
+                    type: 'POST',
+                    data: myform,
+                    async: false,
+                    contentType: false,//不要设置Content-Type请求头
+                    processData: false,// 使数据不做处理
+                    success: function (r) {
+                        if (r.rep) {
+                            o_list = r.rdata["o_rules"]
+                            $('#keywords').dataTable().fnClearTable();
+                            $('#keywords').dataTable().fnAddData(o_list);
+                            showTip("导入成功",1000);
+                        } else {
+                            showTip("导入失败",1000);
+                        }
+                    }
+                })
+            }
+        })
+    });
+    function allSelect(obj) {
+        if ($(obj).is(':checked')) {
+            keyTableChecked = true;
+            keyTableAllChecked = true;
+            $('input[name="ckb-keyid"]').each(function () {
+                this.checked = true;
+                selectIndex.push($(this).parents("tr").index() + 1);
+            })
+        }else {
+            selectIndex.length = 0;
+            keyTableChecked = false;
+            keyTableAllChecked = false;
+            $('input[name="ckb-keyid"]').each(function () {
+                this.checked = false;
+            })
+        }
+    }
+    function singleSelect(obj) {
+        var tag = true;
+        selectIndex.length = 0;
+        $('input[name="ckb-keyid"]').each(function () {
+            if (this.checked) {
+                keyTableChecked = true;
+                selectIndex.push($(this).parents("tr").index() + 1);
+            }else {
+                tag = false
+            }
+        });
+        if (tag) {
+            keyTableAllChecked = true;
+            $('#allCheckbox').prop("checked", true);
+        }else {
+            keyTableAllChecked = false;
+            $('#allCheckbox').prop("checked", false);
+        }
+    }
+    function saveTag() {
+        dataMap.s_tagname = $('#tagname').val()
+        dataMap.s_tagfield = $('#fieldSelect').val()
+        dataMap.s_tasktype = $('#taskSelect').val()
+        dataMap.s_query = $('#query').val()
+        if (dataMap.s_tagname == "" || dataMap.s_tagfield == "" || dataMap.s_tasktype == "") {
+            alert("请填写必须字段!")
+            return
+        }
+        if (o_list.length > 0) {
+            for (const i in o_list) {
+                if (o_list[i].s_matchkey && !o_list[i].s_keymatch) {
+                    showMsg("保存失败,关键词规则中有关键词未对应匹配方式!")
+                    return;
+                }
+                if (o_list[i].s_addkey && !o_list[i].s_addkeymatch) {
+                    showMsg("保存失败,关键词规则中有附加词未对应匹配方式!")
+                    return;
+                }
+            }
+        }
+        dataMap["o_list"] = JSON.stringify(o_list);
+        $.ajax({
+            url: "/service/tag_rule/save",
+            type: 'POST',
+            data: dataMap,
+            success: function (r) {
+                if (r.rep && r.id) {
+                    dataMap["id"]= r.id;
+                    showTip("保存成功", 1000);
+                } else {
+                    showTip("保存失败", 1000);
+                }
+            }
+        })
+    }
+    function selectKeyMatch(val) {
+        setValue = val
+        if (selectIndex.length > 0 && keyTableChecked) {
+            matchCode.length = 0;
+            matchName.length = 0;
+            $('#modal-select-match').modal("show");
+        }else {
+            alert("请选中关键词")
+        }
+    }
+    //匹配方式按钮点击事件
+    function clickMatchBtn(obj) {
+        if ($(obj).hasClass("active-btn-match")) {
+            $(obj).removeClass("active-btn-match")
+            matchCode.splice($.inArray($(obj).attr("code"), matchCode), 1);
+            matchName.splice($.inArray($(obj).val(), matchName), 1)
+        } else {
+            $(obj).addClass("active-btn-match");
+            matchCode.push($(obj).attr("code"));
+            matchName.push($(obj).val())
+        }
+
+        $('#btnGroupMatch2 .btn-default').each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+    }
+    function clickMatchBtn2(obj) {
+        matchCode.length = 0;
+        matchName.length = 0;
+        if ($(obj).hasClass("active-btn-match")) {
+            $(obj).removeClass("active-btn-match")
+            matchCode.splice($.inArray($(obj).attr("code"), matchCode), 1);
+            matchName.splice($.inArray($(obj).val(), matchName), 1)
+        } else {
+            $(obj).addClass("active-btn-match");
+            matchCode.push($(obj).attr("code"));
+            matchName.push($(obj).val())
+            $('#btnGroupMatch2 .btn-default').each(function () {
+                if (this != obj) {
+                    $(this).removeClass("active-btn-match");
+                }
+            });
+        }
+
+        $('#btnGroupMatch .btn-default').each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+    }
+    //匹配方式保存
+    function saveMatch() {
+        $('#btnGroupMatch').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+        $('#btnGroupMatch2').find("input").each(function () {
+            $(this).removeClass("active-btn-match");
+        });
+        var matchNameStr = "";
+        var codeStr = "";
+        for (var i in matchName) {
+            if (matchNameStr == "") {
+                matchNameStr = matchName[i];
+            }else {
+                matchNameStr += "," + matchName[i]
+            }
+            if (codeStr == "") {
+                codeStr = matchCode[i]
+            }else {
+                codeStr = codeStr + "," + matchCode[i]
+            }
+        }
+        for (var i in selectIndex) {
+            var j = selectIndex[i] - 1;
+            if (setValue == 4) {
+                if ($("#keywords tbody tr:nth-child("+selectIndex[i]+") td:nth-child(3)").text() != "") {
+                    $("#keywords tbody tr:nth-child("+selectIndex[i]+") td:nth-child("+setValue+")").html(matchNameStr);
+                    o_list[j]["s_keymatch"] = codeStr;
+                }
+            }else if (setValue == 6) {
+                if ($("#keywords tbody tr:nth-child("+selectIndex[i]+") td:nth-child(5)").text() != "") {
+                    $("#keywords tbody tr:nth-child("+selectIndex[i]+") td:nth-child("+setValue+")").html(matchNameStr);
+                    o_list[j]["s_addkeymatch"] = codeStr;
+                }
+            }
+        }
+        $('#modal-select-match').modal("hide");
+        matchName.length = 0;
+        matchCode.length = 0;
+    }
+</script>

+ 72 - 95
src/web/templates/private/tag_rule_list.html

@@ -10,8 +10,8 @@
             <small><a href="/service/tag_rule/create" class="btn btn-primary opr">新增标签规则</a></small>
         </h1>
         <ol class="breadcrumb">
-          <li><a href="#"><i class="fa fa-dashboard"></i> 首页</a></li>
-          <li><a href="/service/rule/list"> 标签规则列表</a></li>
+            <li><a href="#"><i class="fa fa-dashboard"></i> 首页</a></li>
+            <li><a href="/service/rule/list"> 标签规则列表</a></li>
         </ol>
     </section>
     <!-- Main content -->
@@ -24,13 +24,12 @@
                             <thead>
                             <tr>
                                 <th>编号</th>
-                                <th>客户名称</th>
                                 <th>标签名称</th>
-                                <th>销售经理</th>
+                                <th>属性值</th>
+                                <th>任务类型</th>
                                 <th>修改时间</th>
+                                <th>是否启用</th>
                                 <th>操作</th>
-                                <th>功能</th>
-                                <th>查看</th>
                             </tr>
                             </thead>
                         </table>
@@ -42,32 +41,12 @@
         </div>
     </section>
 </div>
-<div class="modal fade" id="modal-preview-href" tabindex="-1" role="dialog" aria-hidden="true">
-    <div class="modal-dialog">
-        <div class="modal-content">
-            <div class="modal-header">
-                <div class="modal-header">
-                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-                    <div class="edit-form">
-                        <div class="edit-info">
-                            <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
-                            <span class="info">链接地址</span>
-                        </div>
-                        <a id="preview-href" target="_blank" style="word-wrap: break-word"></a>
-                    </div>
-                </div>
-            </div>
-            <div class="modal-footer">
-                <input type="button" id="copy" data-clipboard-target="#preview-href" class="btn btn-primary saveBtn" value="复制">
-                <input type="button" onclick="cancelModel()" class="btn btn-default" value="取消">
-            </div>
-        </div>
-    </div><!-- /.modal -->
-</div>
 {{include "com/dialog.html"}}
 {{include "com/footer.html"}}
 <script>
     menuActive("/tag_rule/list");
+    var TagFieldMap = {{.T.tagFieldMap}}
+    var TaskTypeMap = {{.T.taskTypeMap}}
     $(function () {
         ttable = $('#dataTable').DataTable({
             "paging": true,
@@ -94,94 +73,92 @@
                     }
                     ttable.page(redirectpage).draw(false);
                 });
-                this.api().column(0).nodes().each(function(cell, i) {
+                this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;
                 });
             },
             "columns": [
-                {"data": null,width:"5%"},
-                {"data": "s_customer"},
+                {"data": null, width: "5%"},
                 {"data": "s_tagname"},
-                {"data": "s_salesperson"},
-                {"data": "i_updatetime",width:"9%", render: function (val) {
-                  var dt = new Date()
-                  dt.setTime(parseInt(val) * 1000);
-                  return dt.format("yyyy-MM-dd")
-                }},
-                {"data": "_id", width:"11%",render: function (val, a, row, pos) {
-                    var s = [val, row.s_dataid];
-                      tmp = '<div>' +
-                          '<a class="btn btn-sm btn-primary" href="/service/rule/edit?id='+val+'">编辑</a>'+
-                          '<a class="btn btn-sm btn-danger" onclick="del(\''+s+'\')">删除</a>'+
-                          '</div>';
-                      return tmp
+                {"data": "s_tagfield", render: function (val) {
+                    for (const i in TagFieldMap) {
+                        if (val == TagFieldMap[i].code) {
+                            return TagFieldMap[i].name
+                        }
+                    }
                 }},
-                {"data": "_id", width:"20%",render: function (val, a, row, pos) {
-                    var s = [val, row.s_dataid];
-                      tmp = '<div>' +
-                          '<a class="btn btn-sm btn-primary" href="/service/rule/downloadrule?id='+val+'">导出标签</a>'+
-                          '<a class="btn btn-sm btn-info" href="/service/rule/downloadata?s_dataid='+val+'">导出数据</a>'+
-                          '<a class="btn btn-sm btn-warning" onclick="archive(\'' + val + '\')">存档</a>'+
-                          '</div>';
-                      return tmp
+                {"data": "s_tasktype", render: function (val) {
+                        for (const i in TaskTypeMap) {
+                            if (val == TaskTypeMap[i].code) {
+                                return TaskTypeMap[i].name
+                            }
+                        }
+                    }},
+                {"data": "i_updatetime", width: "9%", render: function (val) {
+                    var dt = new Date()
+                    dt.setTime(parseInt(val) * 1000);
+                    return dt.format("yyyy-MM-dd")
                 }},
-                {"data": "_id",width:"15%", render: function (val, a, row, pos) {
-                  tmp = '<div xmlns="http://www.w3.org/1999/html">' +
-                       '<button class="btn btn-sm btn-instagram" onclick="preview(\'' + row.s_dataid + '\')">链接地址</button>'+
-                      '<a class="btn btn-sm btn-success" href="/service/rule/history?tagid='+val+'">变更历史</a>'+
-                      '</div>';
-                  return tmp
+                {"data": "i_isuse", render: function (val, a, row) {
+                        tmp = ""
+                        if(val == 1){
+                            tmp="<a href='#' title='停用' onclick='setup(\""+row._id+"\",false)'><i class='fa fa-fw fa-circle text-green'></i></a>已启用"
+                        }else{
+                            tmp="<a href='#' title='启用' onclick='setup(\""+row._id+"\",true)'><i class='fa fa-fw fa-circle text-red'></i></a>未启用"
+                        }
+                        return tmp
+                    }, width: "11%"
+                },
+                {"data": "_id", width: "11%", render: function (val, a, row, pos) {
+                    tmp = '<div>' +
+                        '<a class="btn btn-sm btn-primary" href="/service/tag_rule/edit?id=' + val + '">编辑</a>' +
+                        '<a class="btn btn-sm btn-danger" onclick="del(\'' + val + '\')">删除</a>' +
+                        '</div>';
+                    return tmp
                 }}
             ]
         });
     });
-    function del(s){
-        showConfirm("确定删除?", function() {
+
+    function del(s) {
+        showConfirm("确定删除?", function () {
             $.ajax({
-                url:"/service/rule/del",
-                type:"post",
-                data:{"_id": s.split(",")[0], "s_dataid": s.split(",")[1]},
-                success:function(r){
-                  if(r.rep){
-                    ttable.ajax.reload();
-                  }else{
-                    alert("删除失败");
-                  }
+                url: "/service/tag_rule/del",
+                type: "post",
+                data: {"_id": s},
+                success: function (r) {
+                    if (r.rep) {
+                        ttable.ajax.reload();
+                    } else {
+                        alert("删除失败");
+                    }
                 }
             })
         });
     }
-    function archive(_id){
-        showConfirm("是否存档?", function() {
+    function setup(val, bol) {
+        var msg = ""
+        var i_isuse = 0
+        if (bol) {
+            msg = "确定启用?"
+            i_isuse = 1
+        }else {
+            msg = "确定停用?"
+            i_isuse = 0
+        }
+        showConfirm(msg, function() {
             $.ajax({
-                url:"/service/rule/archive",
+                url:"/service/tag_rule/setup",
                 type:"post",
-                data:{"_id":_id},
+                data:{"_id": val, "i_isuse": i_isuse},
                 success:function(r){
-                  if(r.rep){
-                    showTip("存档成功",1000);
-                    //ttable.ajax.reload();
-                  }else{
-                    showTip("存档失败",1000);
-                  }
+                    if(r.rep){
+                        window.location.reload()
+                    }else{
+                        showTip("启用失败", 1000);
+                    }
                 }
             })
         });
     }
-    function preview(s_dataid) {
-        var href = {{.T.preview_href}} + "?type=private"+"&key=" + s_dataid;
-        $('#preview-href').html(href);
-        $('#preview-href').attr("href", href);
-        $('#modal-preview-href').modal("show")
-    }
-    function cancelModel() {
-        $('#modal-preview-href').modal("hide");
-    }
-    var clipboard = new ClipboardJS('#copy');
-    clipboard.on('success', function () {
-        alert("复制成功!")
-    });
-    clipboard.on('error', function () {
-        alert("复制失败!")
-    });
 </script>