Browse Source

no message

Jianghan 3 years ago
parent
commit
eb430694e9
6 changed files with 580 additions and 194 deletions
  1. 1 4
      src/config.json
  2. 0 9
      src/front/front.go
  3. 251 38
      src/front/server.go
  4. 2 2
      src/web/templates/detail.html
  5. 287 135
      src/web/templates/re_detail.html
  6. 39 6
      src/web/templates/review.html

+ 1 - 4
src/config.json

@@ -26,10 +26,7 @@
     "fields":{
     	"projectname": true,
 		"area": true,
-		"projectcode": true,
-		"purchasinglist": true,
-		"package": true,
-		"winnerorder": true
+		"projectcode": true
 	},
     "es":{
     	"addr": "http://192.168.3.206:9800",

+ 0 - 9
src/front/front.go

@@ -525,8 +525,6 @@ func BzJBZD(content []interface{}, set, unset, errset map[string]interface{}) {
 			}
 		}
 	}
-	//qu.Debug("set---", set)
-	// qu.Debug("unset---", unset)
 }
 
 //标注时间地点
@@ -626,9 +624,6 @@ func BzBDXX(content []interface{}, set, unset, errset map[string]interface{}, is
 			unset["purchasinglist"] = ""
 		}
 	}
-	qu.Debug("set---", set)
-	qu.Debug("errset---", errset)
-	qu.Debug("unset---", unset)
 }
 
 //标注多包信息
@@ -751,7 +746,6 @@ func BzDBXX(content []interface{}, set, unset, errset map[string]interface{}, is
 
 //标注中标候选人信息
 func BzZBHXRXX(content []interface{}, set, unset, errset map[string]interface{}, isext bool, status int) {
-	//qu.Debug("是否抽取:", status, isext, len(content), errset)
 	if status == -1 {
 		return
 	}
@@ -807,9 +801,6 @@ func BzZBHXRXX(content []interface{}, set, unset, errset map[string]interface{},
 			unset["winnerorder"] = ""
 		}
 	}
-	qu.Debug("set---", set)
-	qu.Debug("unset---", unset)
-	qu.Debug("errset---", errset)
 }
 
 //标注其余信息

+ 251 - 38
src/front/server.go

@@ -45,6 +45,7 @@ type Front struct {
 	reviewDetail  xweb.Mapper `xweb:"/center/reviewdetail/(.*).html"`
 	reviewSave    xweb.Mapper `xweb:"/center/reviewsave"`
 	reviewStat	  xweb.Mapper `xweb:"/center/review/result"`
+	reviewNext	  xweb.Mapper `xweb:"/center/review/next"`
 }
 
 var preKey = "ck_"
@@ -798,8 +799,9 @@ func (i *Front) Review() error {
 		},
 	}).All(&labeler)
 
-	qu.Debug(labeler)
 	i.T["users"] = labeler
+	qu.Debug(util.Config.Fields)
+	i.T["fields"] = util.Config.Fields
 	return i.Render("review.html", &i.T)
 }
 
@@ -813,8 +815,7 @@ func (i *Front) ReviewList() {
 			q["modifyuser"] = user
 		}
 		qu.Debug(q, util.Config.Fromtable)
-		datas, b := util.MgoM.Find(util.Config.Fromtable, q, nil, nil, false, -1, -1)
-		qu.Debug(*datas)
+		datas, b := util.MgoM.Find(util.Config.Fromtable, q, bson.M{"_id": 1}, nil, false, -1, -1)
 		if b && len(*datas) > 0 {
 			i.ServeJson(map[string]interface{}{
 				"rep":  b,
@@ -834,7 +835,6 @@ func (i *Front) ReviewDetail(id string) error {
 	defer qu.Catch()
 	coll, _ := i.GetSession("coll").(string)
 	query, _ := i.GetSession("query").(map[string]interface{})
-	qu.Debug(coll, query)
 	rep := getDetail(id, coll)          //获取本条公告的信息
 	i.T["otherInfo"] = rep["otherInfo"] //展示关联公告信息
 	i.T["moreInfo"] = rep["moreInfo"]   //更多关联公告信息
@@ -859,15 +859,218 @@ func (i *Front) ReviewDetail(id string) error {
 	i.T["worder_new"] = rep["worder_new"]
 	i.T["pcl_new"] = rep["pcl_new"]
 	i.T["pkg_new"] = rep["pkg_new"]
+	i.T["fields"] = util.Config.Fields
 	i.T["nextid"] = GetNextDataId(id, coll, query)              //下一条id
 	return i.Render("re_detail.html", &i.T)
 }
 
-
-func (i *Front) ReviewSave() {
+func (i *Front) ReviewSave() error {
 	defer qu.Catch()
-	//_id := i.GetString("_id")
+	b := false
+	obj := []map[string]interface{}{}
+	key := i.GetString("key")
+	_id := i.GetString("_id")
+	//stype, _ := i.GetInteger("stype")
+	err := json.Unmarshal([]byte(key), &obj)
+	if err != nil {
+		i.ServeJson(b)
+		return nil
+	}
+	set := map[string]interface{}{}    //更新、新增字段
+	unset := map[string]interface{}{}  //删除字段
+	errset := map[string]interface{}{} //记录修改的字段信息
+	isSaveMarked := false
+	if len(obj) == 1 { //单独保存某个一级
+		content, ok := obj[0]["content"].([]interface{})
+		if !ok || len(content) == 0 {
+			i.ServeJson(b)
+			return nil
+		}
+		title := qu.ObjToString(obj[0]["title"])
+		isext, _ := obj[0]["checkType"].(bool)
+		istag, _ := obj[0]["checkAllTag"].(bool)
+		status := qu.IntAll(obj[0]["status"])
+		switch title {
+		case "基本字段":
+			BzJBZD(content, set, unset, errset)
+		case "时间地点":
+			BzSJDD(content, set, unset, errset)
+		case "标的信息":
+			BzBDXX(content, set, unset, errset, isext, istag, status)
+		case "多包信息":
+			BzDBXX(content, set, unset, errset, isext, status)
+		case "中标候选人信息":
+			BzZBHXRXX(content, set, unset, errset, isext, status)
+		case "其余信息":
+			BzQYXX(content, set, unset, errset)
+		}
+	} else {
+		isSaveMarked = true
+		for j, val := range obj {
+			content, ok := val["content"].([]interface{})
+			status := qu.IntAll(val["status"])
+			if !ok {
+				continue
+				// i.ServeJson(b)
+				// return nil
+			}
+			isext, _ := val["checkType"].(bool)
+			istag, _ := val["checkAllTag"].(bool)
+			if j == 0 { //基本信息
+				BzJBZD(content, set, unset, errset)
+			} else if j == 1 { //时间地点
+				BzSJDD(content, set, unset, errset)
+			} else if j == 2 { //标的物
+				BzBDXX(content, set, unset, errset, isext, istag, status)
+			} else if j == 3 { //多包
+				BzDBXX(content, set, unset, errset, isext, status)
+			} else if j == 4 { //候选人
+				BzZBHXRXX(content, set, unset, errset, isext, status)
+			} else { //其余信息
+				BzQYXX(content, set, unset, errset)
+			}
+		}
+	}
+	userInfo := map[string]interface{}{}     //记录本次标注日志
+	modifyFields := map[string]interface{}{} //本次标注所有字段
+	unerrset := map[string]interface{}{}     //记录errdata错误信息表删除
+
+	loginuser := i.GetSession("loginuser").(string)
+	coll := i.GetSession("coll").(string)
+	data, _ := util.MgoM.FindById(coll, _id, nil) //查询标注保存前的原始信息
+	//modifyuser := qu.ObjToString((*data)["modifyuser"])
+
+	remap := make(map[string]interface{})		// 质检信息
+	reField := make(map[string]interface{})
+	remap["user"] = loginuser
+	remap["updatetime"] = time.Now().Unix()
+
+	//标注多次操作处理
+	if len(set) > 0 { //set中为本次标注保存的数据(ck_bidopentime:1;ck_buyer:2;buyer:"XXX")
+		for s, sv := range set {
+			//特殊字段处理
+			if s == "ck_pclistag" && (*data)["ck_pclistag"] != nil {
+				delete(set, s)
+				continue
+			}
+			//区分是标记字段,还是普通字段(标记字段:ck_buyer;普通字段:buyer)
+			if strings.HasPrefix(s, preKey) {
+				status := qu.IntAll(sv)                                        //标注字段状态
+				field := s[3:]                                                 //去除前缀,被标注字段
+				checkedStatus := qu.IntAll((*data)[s])                         //数据库被标注状态
+				rename := strings.Replace(s, "ck_", "re_", -1)
+				reField[rename] = status
+				if status == 1 && (checkedStatus == 2 || checkedStatus == 1) { //数据库已有标记,且页面标注正确,此次该字段不做标注保存
+					delete(set, field)
+					delete(set, s)
+					continue
+				} else {
+					if set[field] == nil && status != 2 { //表示该字段没有要修改的值,此时标记为1或2(亦或是ck_wodrisext;ck_pkgisext;ck_pclisext)
+						modifyFields[field] = set[s] //目前会有pclisext、pclistag、pkgisext、wodrisext
+						continue
+					} else { //此时有修改的值和标记2
+						modifyFields[field] = status //记录标注的字段和状态
+						if checkedStatus != 0 {      //已有标注信息的状态
+							if status == 2 && checkedStatus == 2 { //字段已被修改且本次也为修改
+								errdata, _ := util.MgoM.FindById(util.Config.Totablel, _id, map[string]interface{}{"userinfo": 0})
+								if errdata != nil && len(*errdata) != 0 {
+									delete(errset, field) //errdata中有该字段的错误记录,不再更新errdata
+									//对比errdata错误值:相等变为1,errdata删除;不等变为2,标注表修改该字段
+									errText := fmt.Sprint((*errdata)[field])
+									text := fmt.Sprint(set[field])
+									if errText == text {
+										set[s] = 1           //更新标注表字段状态
+										unerrset[field] = "" //删除errdata表字段
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	remap["field"] = reField
+	set["review"] = remap
+	set["re_data"] = 1
+	//存储原错误信息
+	//1、errdata操作
+	errUpdata := map[string]interface{}{} //errdata所有要更新内容
+	for f, _ := range errset {
+		errset[f] = (*data)[f]
+	}
+	if len(modifyFields) > 0 { //有标注字段,记录标注信息
+		errset["updatetime"] = time.Now().Unix()
+		errset["modifyuser"] = loginuser
+		userInfo["fields"] = modifyFields
+		userInfo["updatetime"] = time.Now().Unix()
+		userInfo["modifyuser"] = loginuser
+		errUpdata["$push"] = map[string]interface{}{
+			"userinfo": map[string]interface{}{
+				"$each":     []interface{}{userInfo},
+				"$position": 0,
+			},
+		}
+	}
+	if len(errset) > 0 {
+		errUpdata["$set"] = errset
+	}
+	if len(unerrset) > 0 {
+		errUpdata["$unset"] = unerrset
+	}
+	if len(errUpdata) > 0 {
+		util.MgoM.Update(util.Config.Totablel, `{"_id":"`+_id+`"}`, errUpdata, true, false)
+	}
+	//更新表操作
+	//更新正确信息
+	update := map[string]interface{}{}
+	if len(set) > 0 {
+		if len(set) > 1 {
+			set["updatetime"] = time.Now().Unix()
+			set["modifyuser"] = loginuser
+		}
+		update["$set"] = set
+	}
+	if len(unset) > 0 {
+		update["$unset"] = unset
+	}
+	if len(update) > 0 {
+		b = util.MgoM.Update(coll, `{"_id":"`+_id+`"}`, update, false, false)
+		if b {
+			if coll != util.Config.Fromtable && isSaveMarked { //util.coll此时的标注表  util.Config.Fromtable默认标注表
+				data, _ := util.MgoM.FindById(coll, _id, nil)
+				if data != nil && len(*data) > 0 {
+					update := map[string]interface{}{"$set": *data}
+					if len(unset) > 0 {
+						update["$unset"] = unset
+					}
+					if !util.MgoM.Update(util.Config.Fromtable, map[string]interface{}{"_id": (*data)["_id"]}, update, true, false) {
+						qu.Debug("同步marked失败,", _id)
+					}
+				}
+			}
+		}
+		i.ServeJson(b)
+	} else {
+		i.ServeJson(true)
+	}
+
+	return nil
+}
 
+func (i *Front) ReviewNext() {
+	defer qu.Catch()
+	id := i.GetString("id")
+	coll := i.GetSession("coll").(string)
+	q := bson.M{"_id": bson.M{"$gt": mgo.StringTOBsonId(id)}}
+	info, b := util.MgoM.Find(coll, q, bson.M{"_id": 1}, bson.M{"_id": 1}, false, 0, 1)
+	qu.Debug(q)
+	if b && len(*info) > 0 {
+		nxid := mgo.BsonIdToSId((*info)[0]["_id"])
+		i.ServeJson(bson.M{"id": nxid, "exists": true})
+	}else {
+		i.ServeJson(bson.M{"exists": false})
+	}
 }
 
 func (i *Front) ReviewStat() {
@@ -879,47 +1082,57 @@ func (i *Front) ReviewStat() {
 
 	cmaps := make(map[string]int)			// 标注字段整体准确率
 	umaps := make(map[string]interface{})	// 按人员 字段准确率
-	//for _, i2 := range util.Config.Field {
-	//	cmaps[i2] = 0
-	//}
+	for k, i2 := range util.Config.Fields {
+		if i2 {
+			cmaps[k] = 0
+		}
+	}
 	for tmp := make(map[string]interface{}); result.Next(&tmp); {
 		count ++
 		if qu.IntAll(tmp["ck_data"]) >= 1 {
 			cmark ++
 		}
-		if qu.IntAll(tmp["review"]) > 0 {
+		if qu.IntAll(tmp["re_data"]) > 0 {
 			rmark ++
-			if reField, ok := tmp["re_field"].(map[string]interface{}); ok {
-				if user, o1 := tmp["modifyuser"].(string); o1 {
-
-					// 每个人员标注的质检数量
-					if umaps["count"] != nil {
-						umaps["count"] = qu.IntAll(umaps["count"]) + 1
-					}else {
-						umaps["count"] = 1
-					}
-					// 按人员统计每个字段
-					var ump map[string]int
-					if umaps[user] != nil {
-						ump, _ = umaps[user].(map[string]int)
+			if reField, ok := tmp["review"].(map[string]interface{}); ok {
+				remap, _ := reField["field"].(map[string]interface{})
+				flag := true			// 数据整体准确率
+				// 按人员统计字段准备率
+				user := qu.ObjToString(tmp["modifyuser"])
+				var up map[string]int
+				if umaps[user] == nil {
+					up = make(map[string]int)
+				}else {
+					up = umaps[user].(map[string]int)
+				}
+				for k1 := range cmaps{
+					k2 := "re_" + k1
+					if qu.IntAll(remap[k2]) == 1 {
+						cmaps[k1] += 1			// 字段整体正确率
+						up[k1] += 1
 					}else {
-						ump = make(map[string]int)
-					}
-
-					flag := true			// 数据整体准确率
-					for k, v := range reField{
-						if v == 1 {
-							cmaps[k] ++
-							ump[k] ++
-						}else {
-							flag = false
-						}
-					}
-					if flag {
-						rgmark ++
+						flag = false
 					}
 				}
+				up["count"] += 1
+				umaps[user] = up
+				if flag {
+					rgmark ++
+				}
 			}
 		}
 	}
+
+	qu.Debug("count:", count, ",cmark:", cmark, ",rmark:", rmark, ",rgmark:", rgmark)
+	qu.Debug(cmaps)
+	qu.Debug(umaps)
+	save := bson.M{"total_count": count, "cmake_count": cmark, "rmark_count": rmark, "rgmark_count": rgmark}
+	save["result"] = cmaps
+	save["user_result"] = umaps
+	id := util.MgoM.Save("review_result", save)
+	if id != "" {
+		i.ServeJson(map[string]interface{}{"rep": true})
+	}else {
+		i.ServeJson(map[string]interface{}{"rep": false})
+	}
 }

+ 2 - 2
src/web/templates/detail.html

@@ -1234,9 +1234,9 @@
                 console.log(this.editData)
                 var noTagKey = [];
                 this.editData.filter(function (one) {
-                  console.log("title---",one.title,one.status)
+<!--                   console.log("title---",one.title,one.status) -->
                   if(one.title == "标的信息"||one.title == "多包信息"||one.title == "中标候选人信息"){
-                    if(one.status == -1){
+                    if(allCheckFields[one.title] && one.status == -1){
                       noTagKey.push(one.title);
                     }
                   }else{

+ 287 - 135
src/web/templates/re_detail.html

@@ -70,6 +70,31 @@
          .top-button-group button {
           margin-bottom: 12px;
         }
+         .el-radio-button--mini.info .el-radio-button__inner {
+            color: #909399 !important;
+            background: #f4f4f5 !important;
+            border-color: #d3d4d6 !important;
+        }
+        .default .el-radio-button__orig-radio+.el-radio-button__inner{
+              color: #409eff;
+              background: #ecf5ff;
+              border-color: #b3d8ff;
+        }
+        .success .el-radio-button__orig-radio+.el-radio-button__inner {
+            color: #67c23a;
+            background: #f0f9eb;
+            border-color: #c2e7b0;
+        }
+        .success .el-radio-button__orig-radio:checked+.el-radio-button__inner,
+        .default .el-radio-button__orig-radio:checked+.el-radio-button__inner {
+            color: #FFF;
+            background-color: #409EFF;
+            border-color: #409EFF;
+            -webkit-box-shadow: -1px 0 0 0 #409EFF;
+            box-shadow: -1px 0 0 0 #409EFF
+        }
+
+
     </style>
     <script>
         function prettyPrint(obj) {
@@ -83,7 +108,6 @@
 
             return (function innerPrettyPrint(obj, spaces) {
                 var type = typeof obj;
-                //console.log(obj,type)
                 if (type == "number" || type == "boolean") {
                     return obj.toString();
                 } else if (type == "string") {
@@ -96,18 +120,15 @@
                     var thisIndent = ' '.repeat(spaces);
                     var subIndent  = thisIndent + ' '.repeat(INDNET_SPACES);
                     var subSpaces = spaces + INDNET_SPACES;
-
                     if (Object.prototype.toString.call(obj) == '[object Object]') {
                         for(var k in obj) {
                             entries.push('"' + k + '": ' + innerPrettyPrint(obj[k], subSpaces));
                         }
-
                         return OBJ_BEGIN + ENDLINE + subIndent + entries.join(COMMA_ENDLINE + subIndent) + ENDLINE + thisIndent + OBJ_END;
                     } else if (Object.prototype.toString.call(obj) == '[object Array]') {
                         obj.forEach(function(a) {
                             entries.push(innerPrettyPrint(a, subSpaces));
                         });
-
                         return ARR_BEGIN + ENDLINE + subIndent + entries.join(COMMA_ENDLINE + subIndent) + ENDLINE + thisIndent + ARR_END;
                     }  else if (obj === null) {
                         return "null";
@@ -125,17 +146,19 @@
         <!--文章区-->
         <div class="article" >
             <div class="top-button-group">
-              <el-button-group>
-                <el-button  type="primary" plain size="mini" @click="activeLabel = '原文'">原文</el-button>
+              <el-radio-group v-model="activeLabel"  size="mini">
+                <el-radio-button class="default" label="原文"></el-radio-button>
                 {{if .T.info.filetext}}
-                <el-button  type="primary" plain size="mini" @click="activeLabel = '附件'">附件</el-button>
+                <el-radio-button class="default" label="附件"></el-radio-button>
                 {{end}}
-              </el-button-group>
-              <el-button-group v-for="(item, index) in otherInfo">
-                <el-button  type="success" plain size="mini"  @click="activeLabel = item.subtype">[[item.subtype]]</el-button>
-                <el-button type="success" plain size="mini"  v-if="item.filetext" @click="activeLabel = item.subtype + '-附件'">附件</el-button>
-              </el-button-group>
-              <el-button-group v-if="moreInfo&&moreInfo.length > 0">
+              </el-radio-group>
+
+              <el-radio-group v-model="activeLabel" v-for="(item, index) in otherInfo"  size="mini">
+                <el-radio-button class="success" :label="item.subtype">[[item.subtype]]</el-radio-button>
+                <el-radio-button class="success" :label="item.subtype + '-附件'">附件</el-radio-button>
+              </el-radio-group>
+
+              <el-radio-group v-if="moreInfo&&moreInfo.length > 0"  size="mini">
                 <el-popover
                   placement="right-end"
                   trigger="hover">
@@ -148,11 +171,11 @@
                       </template>
                     </el-table-column>
                   </el-table>
-                 <el-button slot="reference" style="border-color: #d3d4d6;"  size="mini" type="info" plain>更多</el-button>
+                 <el-radio-button class="info" slot="reference" style="border-color: #d3d4d6;">更多</el-radio-button>
                 </el-popover>
-              </el-button-group>
+              </el-radio-group>
             </div>
-            
+
             <hr style="border:1 double;" width="100%">
             <br><a v-if="getPageInfo.href.length > 0" :href="getPageInfo.href" target="_blank">查看原文</a>
             <!--<a href="{{.T.jyhref}}" target="_blank">剑鱼链接</a>-->
@@ -170,14 +193,20 @@
                     <div class="edit-title" @click="one.show = !one.show">
                         <span>[[one.title]]</span>
                         <div class="button-group">
+                            <div v-if="one.showCheck">
+                                <input :id="one.title" v-show="one.title == '标的信息'" @click.stop type="checkbox" v-model="one.checkAllTag">
+                                <label @click.stop v-show="one.title == '标的信息'" :for="one.title">全部标注</label>
+                            </div>
+                           <!-- &nbsp;
                             <div v-if="one.showCheck">
                                 <input :id="one.title" @click.stop type="checkbox" v-model="one.checkType">
                                 <label @click.stop :for="one.title">是否抽取</label>
-                            </div>
+                            </div>-->
                             <div class="button-box">
                                 <!--v-show="one.title == '基本字段'"-->
                                 <button  class="pass success" @click.stop="saveDataOne(one,'1')" style="font-size: 14px;width: auto;float:left;">通过</button>
                                 <button  class="pass default" @click.stop="saveDataOne(one,'-1')" style="font-size: 14px;width: auto;float:left">取消</button>
+                                <!--              						  <button class="pass" @click.stop="open(one, true)"  style="font-size: 14px;width: auto;float:left">保存</button>-->
                             </div>
                             <!--<button class="add" v-show="one.title != '基本'" @click.stop="one.content.push(getTemp(2));goMark2(500)">+</button>-->
                             <!--<button class="add" v-show="one.title == '基本'" @click.stop="one.content[0].content.push(getTemp(3));goMark2(60)">+</button>-->
@@ -204,7 +233,7 @@
                                     <div class="edit-title" v-if="two.title" @click="two.show = !two.show">
                                         <span>[[two.title]]</span>
                                         <div class="button-box" :style="one.title == '多包信息' ? 'margin-right: 193px' : ''">
-                                            <button v-if="one.title == '多包信息'"  class="pass a-button" @click.stop="addThreeChild(two,'2',one)" style="font-size: 14px;margin: 0;width: auto;float:left;">新增中标信息</button>
+                                            <button v-if="one.title == '多包信息'"  class="pass a-button" @click.stop="addThreeChild(two,'2',one)" style="font-size: 14px;margin: 0;width: auto;float:left;">新增子包中标信息</button>
                                             <button class="pass success" @click.stop="saveDataTwo(two,'1',one)" style="font-size: 14px;width: auto;float:left;">通过</button>
                                             <button class="pass default" @click.stop="saveDataTwo(two,'-1',one)" style="font-size: 14px;width: auto;float:left">取消</button>
                                         </div>
@@ -299,17 +328,32 @@
                 </div>
             </div>
             <div class="save-box">
-<!--                 <button  class="code" @click.stop="open(1)" style="width:100px">全部验证</button> -->
-<!--                 <button  class="code" @click.stop="open(2)" style="width:100px">字段验证</button> -->
-                <button  class="code" @click.stop="open('')" style="width:100px">保存</button>&nbsp;&nbsp;
-                <button  class="code" @click.stop="openHref" style="width:100px">下一条</button>
+                <button  class="code" @click.stop="open('', false)" style="width:100px">保存</button>&nbsp;&nbsp;
+                <button  class="code" @click.stop="openHref" style="width:100px;margin-left:50px">下一条</button>
             </div>
         </div>
     </div>
+    <!--弹出层-->
+    <dialog class="dialog" v-if="showPop">
+        <span class="close" @click="showPop = false;changeText()">x</span>
+        <div class="pop">
+            <div class="title">源码</div>
+            <div class="con"  ref="text" contentEditable="true">
+                <pre  v-html="addStyle(editData)"></pre>
+            </div>
+            <button @click="showPop = false;changeText();upChange()">保&nbsp;存</button>
+        </div>
+    </dialog>
+    <dialog id="com-alert" class="dialog" style="background: rgba(124, 124, 125, 0.1);z-index:9999;display: none;">
+        <div class="pop" style="background: rgba(124, 124, 125, 0.1);">
+            <div id="com-alert-val" class="title" style="color:red">保存成功</div>
+        </div>
+    </dialog>
 </main>
 
 </body>
 <script>
+  var allCheckFields  = {{.T.fields}};//本次需标注的所有字段
   // 页面数据
   var pageDataMap = {
     '原文': {
@@ -325,10 +369,8 @@
   }
   // 更多关联信息
   var moreInfo = {{.T.moreInfo}}
-  console.log(moreInfo)
   //公告关联信息
   var otherInfo = {{.T.otherInfo}};
-  console.log(otherInfo)
   //快捷键
   $(document).keydown(function(event){
     if(!event.shiftKey) {
@@ -367,25 +409,25 @@
       }else{
         app.changeBaseValue(5, text, 2)//填充
       }
-    }else if(event.keyCode == 90){//预算快捷键z
+    }else if(event.keyCode == 65){//预算快捷键a
       if(event.shiftKey){
         app.changeBaseValue(6, '', 2) //删除对应文本
       }else{
         app.changeBaseValue(6, text, 2)//填充
       }
-    }else if(event.keyCode == 88){//中标金额快捷键x
+    }else if(event.keyCode == 90){//中标金额快捷键z
       if(event.shiftKey){
         app.changeBaseValue(7, '', 2) //删除对应文本
       }else{
         app.changeBaseValue(7, text, 2)//填充
       }
-    }else if(event.keyCode == 65){//采购单位快捷键a
+    }else if(event.keyCode == 83){//采购单位快捷键s
       if(event.shiftKey){
         app.changeBaseValue(8, '', 2) //删除对应文本
       }else{
         app.changeBaseValue(8, text, 2)//填充
       }
-    }else if(event.keyCode == 83){//代理机构快捷键s
+    }else if(event.keyCode == 88){//代理机构快捷键x
       if(event.shiftKey){
         app.changeBaseValue(9, '', 2) //删除对应文本
       }else{
@@ -421,15 +463,14 @@
       //return document.selection.createRange().htmlText;
       //return document.selection.createRange().text; //只复制文本
     }
-    text = text.replace(/(\r|\n|\s+|&nbsp;|\<br\>|\<br\/\>)/g, "")
+    text = text.replace(/(\r|\n|\s+|&nbsp;|<[^>]*>|<\/[^>]*)/g, "")
     return text;
   }
-  
+
     //记录是否点击保存
     var issave = false;
     var _id = {{.T.info._id}};
     var nextid = {{.T.nextid}};
-    //console.log(nextid)
     //基本信息
     var common={{.T.common}};
     var uInput=[];
@@ -455,6 +496,11 @@
             tmp.selectArr=['是','否']
         }
         tmp.status=common[k].status
+        if(common[k].key== "bidamounttype"){
+          tmp.select = common[k].value ? common[k].value : '金额'
+          tmp.selectArr=['金额','折扣率','单价']
+          tmp.status = -1
+        }
         uInput[k]=tmp
     }
     //时间地点
@@ -502,9 +548,9 @@
         var content={};
         content.title="候选人"
         content.show=true
-        content.status=-1
+        content.status=worder_new[k]["status"]
         content.uInput=c_uInput
-        content.ck_isnew=worder_new[k] || false
+        content.ck_isnew=worder_new[k]["isnew"] || false
         content.content=[]
         c_content[k]=content
     }
@@ -521,19 +567,19 @@
             tmp.input=purchasinglist[k][i].value
             tmp.key=purchasinglist[k][i].key
             tmp.status=purchasinglist[k][i].status
-            if(purchasinglist[k][i].key== "pclisover"){
-              tmp.select = purchasinglist[k][i].value ? purchasinglist[k][i].value : '是'
-              //tmp.select=purchasinglist[k][i].value
-              tmp.selectArr=['是','否']
-            }
+            //if(purchasinglist[k][i].key== "pclisover"){
+            //  tmp.select = purchasinglist[k][i].value ? purchasinglist[k][i].value : '是'
+            //  //tmp.select=purchasinglist[k][i].value
+            //  tmp.selectArr=['是','否']
+            //}
             c_uInput[i]=tmp
         }
         var content={};
         content.title="标的物"
         content.show=true
-        content.status=-1
+        content.status=pcl_new[k]["status"]
         content.uInput=c_uInput
-        content.ck_isnew=pcl_new[k] || false
+        content.ck_isnew=pcl_new[k]["isnew"] || false
         content.content=[]
         pcl_content[k]=content
     }
@@ -559,10 +605,15 @@
             tmp.input=pack[i].value
             tmp.key=pack[i].key
             tmp.status=pack[i].status
+            if(pack[i].key== "bidamounttype"){
+              tmp.select = pack[i].value ? pack[i].value : '金额'
+              tmp.selectArr=['金额','折扣率','单价']
+              tmp.status = 1
+            }
             uInputs[i]=tmp
         }
-        
-        //子包候选人
+
+        //中标人信息
         var winnerall = packs[k]["winnerall"]
         for(i in winnerall){
           var tmp={}
@@ -575,12 +626,12 @@
         var content={};
         content.title="子包";
         content.show=true;
-        content.status=-1
+        content.status=packs[k]["packstatus"];
         content.uInput=uInputs;
         content.ck_isnew=pkg_new[k] || false
         content.num = packskey[k];
         p_content[k]=content;
-      
+
     }
 
     var pclf = {{.T.PurchasinglistField}};
@@ -593,14 +644,14 @@
               status:"2",
               title:pclf[i][key]
           }
-          if(key== "pclisover"){
-            tempNode.select= '是'
-            tempNode.selectArr=['是','否']
-          }
+          //if(key== "pclisover"){
+          //  tempNode.select= '是'
+          //  tempNode.selectArr=['是','否']
+          //}
           pclfInput.push(tempNode)
       }
     }
-    
+
 
     var wodf = {{.T.WinnerorderField}};
     var wodfInput = []
@@ -618,12 +669,17 @@
     var pfInput = []
     for(i in pf){
         for(key in pf[i]){
-            pfInput.push({
-                input:"",
-                key:key,
-                status:"2",
-                title:pf[i][key]
-            })
+            var tempNode = {
+              input:"",
+              key:key,
+              status:"2",
+              title:pf[i][key]
+            }
+            if(key== "bidamounttype"){
+              tempNode.select= '金额'
+              tempNode.selectArr=['金额','折扣率','单价']
+            }
+            pfInput.push(tempNode)
         }
     }
     var app = new Vue({
@@ -631,6 +687,7 @@
         delimiters:["[[","]]"],
         data: {
             activeLabel: '原文',
+            nowLabel: ['原文'],
             otherInfo: otherInfo,
             moreInfo: moreInfo,
             scrollCache: {
@@ -674,7 +731,8 @@
                     title: '标的信息',
                     show: false,
                     showCheck: true,
-                    checkType: {{.T.ck_pclisext}},
+                    //checkType: {{.T.ck_pclisext}},
+                    checkAllTag: {{.T.ck_pclistag}},
                     status: {{.T.ck_purchasinglist}},
                     content: pcl_content
                 },
@@ -682,7 +740,7 @@
                     title: '多包信息',
                     show: false,
                     showCheck: true,
-                    checkType: {{.T.ck_pkgisext}},
+                    //checkType: {{.T.ck_pkgisext}},
                     status: {{.T.ck_package}},
                     content: p_content
                 },
@@ -690,7 +748,7 @@
                     title: '中标候选人信息',
                     show: false,
                     showCheck: true,
-                    checkType: {{.T.ck_wodrisext}},
+                    //checkType: {{.T.ck_wodrisext}},
                     status: {{.T.ck_winnerorder}},
                     content: c_content
                 },
@@ -755,7 +813,6 @@
         methods: {
           // 当前输入框数据与原始数据比较
           focusFn (uin, oIndex, tIndex, uIndex, two, one) {
-            //console.log(uin,uin.input, this.originData[oIndex].content[tIndex].uInput[uIndex].input, 'item')
             if(uin.key=="bidendtime"||uin.key=="bidopentime"||uin.key=="project_startdate"||uin.key=="project_completedate"||uin.key=="publishtime"||uin.key=="signaturedate"){
               var val = uin.input
               if(val != ""){
@@ -765,16 +822,22 @@
                     this.$message({
                       message: uin.title+",日期格式错误!正确格式:2006-01-02 15:04:05",
                       type: 'warning',
-                      duration: 3000,
+                      duration: 2000,
                       offset: 300
                     });
                     return
                   }
               }
             }
-            console.log(22222222222)
-            var oNode = this.originData[oIndex].content[tIndex].uInput[uIndex]
-            var changeStatus = uin.input == oNode.input
+            var newNode = this.originData[oIndex].content[tIndex]
+            if(newNode== null){//新增子模块处理
+              return
+            }
+            var oNode =newNode.uInput[uIndex]
+            if(oNode == null){//新增中标人信息处理
+              return
+            }
+            var changeStatus = uin.input == oNode.input//多包中新增的中标信息报错
             if (uin.select) {
               changeStatus = uin.select == oNode.select
             }
@@ -791,7 +854,7 @@
               this.editData[0].content[0].uInput[index].status = status
             }
           },
-            selectchange(uni,status,two,one){//状态更新
+            selectchange(uni,status,two,one){
               if (uni.status == '-1' || uni.status == '2') {
                 status = 2
               }
@@ -802,27 +865,19 @@
                  alert("请先保存数据!")
                  return
               }else{
-                  if(nextid==""){
-                      window.location.href = '/center/finishcheck';
-                  }else{
-                      $.ajax({
-                          url: "/center/checkid",
-                          type: "post",
-                          data: {"id":nextid},
-                          async: false,
-                          success: function (r) {
-                              if(r && r.msg == ""){
-                                  if(r.exists){//标注完成
-                                      window.location.href = "/center/finishcheck";
-                                  }else if (!r.exists){
-                                      window.location.href = "/center/detail/"+r.id+".html"
-                                  }
-                              }else{
-                                  alert("标注出错!"+r.msg)
-                              }
-                          }
-                      })
-                  }
+                  $.ajax({
+                    url: "/center/review/next",
+                    type: "post",
+                    data: {"id": _id},
+                    async: false,
+                    success: function (r) {
+                        if(r.exists){
+                            window.location.href = "/center/reviewdetail/"+r.id+".html"
+                        }else {
+                            alert("没有更新数据了!")
+                        }
+                    }
+                })
               }
             },
             // 检查一级是否需要改变状态
@@ -845,7 +900,6 @@
                     }
                     statusList[tempIndex] = Number(statusList[tempIndex]) + 1
                 }
-
                 if (statusList[1] > 0) {
                     tempObj.obj.status = 1
                 }
@@ -853,7 +907,10 @@
                     tempObj.obj.status = 2
                 }
                 if (statusList[4] === tempObj.list.length) {
-                    tempObj.obj.status = 2
+                    tempObj.obj.status = 4
+                    if(tempObj.obj.title == "标的信息"||tempObj.obj.title == "多包信息"||tempObj.obj.title == "中标候选人信息"){
+                      tempObj.obj.status = 2
+                    }
                 }
                 if (statusList[3] === tempObj.list.length) {
                     tempObj.obj.status = 2
@@ -885,7 +942,7 @@
                           this.$message({
                             message: witch.title+",日期格式错误!正确格式:2006-01-02 15:04:05",
                             type: 'warning',
-                            duration: 3000,
+                            duration: 2000,
                             offset: 300
                           });
                           //alert(witch.title+",日期格式错误!正确格式:2006-01-02 15:04:05")
@@ -893,6 +950,9 @@
                         }
                     }
                 }
+                if (s == '2' && !one && !two && witch.content.length == 0) {
+                  return
+                }
                 witch.status = s;
                 if (two) {
                     this.checkOneStatus({
@@ -904,11 +964,14 @@
             },
             //二级删除
             delNewTwo: function (one, index, two) {
+                //two.ck_isnew = false //目前点删除按钮页面直接不显示,但是集合索引位置不变,所以加了此代码
+                //two.show = false
                 if (two.ck_isnew) {
                     one.content.splice(index, 1)
                 } else {
-                    two.status = 2
-                    this.saveDataTwo(two, 2, one)
+                    two.show = false
+                    two.status = 4
+                    this.saveDataTwo(two, 4, one)
                 }
                 this.checkOneStatus({
                     one: one,
@@ -918,8 +981,7 @@
             },
             /*add style*/
             addStyle: function (data) {
-                //console.dir(data)
-                return prettyPrint(data).replace(/(checkType|showCheck|wstatus|status|key|title|input|content|uInput|selectArr|select|show|true)/g, "<mark>$1</mark>")
+                return prettyPrint(data).replace(/(checkAllTag|checkType|showCheck|wstatus|status|key|title|input|content|uInput|selectArr|select|show|true)/g, "<mark>$1</mark>")
             },
             /*同步修改源码*/
             changeText: function (boolean) {
@@ -968,21 +1030,6 @@
                 $(temp).addClass('focus')
                 document.querySelector('.article').scrollTop = offset(temp).top - window.screen.height / 2
             },
-            //markTag:function(n){
-            //    $.ajax({
-            //        url:"/markTag",
-            //        method:"post",
-            //        data: {tag:n,_id:_id},
-            //        success:function(res){
-            //            if(res){
-            //                document.getElementById("com-alert-val").innerHtml="标记成功";
-            //                var label1 = document.getElementById("com-alert");
-            //                label1.style.display="block";
-            //                setTimeout(function(){label1.style.display="none";},1000)
-            //            }
-            //        }
-            //    });
-            //},
             addChild: function (one, oindex) {
                 var tempNode = {}
                 switch (one.title) {
@@ -997,7 +1044,7 @@
                         }
                         break
                     }
-                    case "多包信息": {pfInput
+                    case "多包信息": {
                         tempNode = {
                             //content: [],
                             show:true,
@@ -1020,9 +1067,6 @@
                         break
                     }
                 }
-                // if (one.status >= 2) {
-                //     one.status = '2'
-                // }
                 one.content.push(tempNode)
                 this.checkOneStatus({
                     one: one,
@@ -1032,7 +1076,7 @@
                   var tempN = $(".edit.one").eq(oindex).find(".edit-title")
                   var goTop = tempN.eq(tempN.length - 1).offset().top
                   setTimeout(() => {
-                    $(".operation").scrollTop(goTop)
+                    $(".operation").scrollTop($(".operation").scrollTop() + goTop)
                   }, 150)
                 })
             },
@@ -1048,7 +1092,7 @@
                 input:"",
                 key: 'bidamount',
                 status:"2",
-                title: '标段(包)中金额'
+                title: '标段(包)中金额'
               })
               two.status = 2
               this.checkOneStatus({
@@ -1070,7 +1114,7 @@
                                 this.$message({
                                   message: v.title+",日期格式错误!正确格式:2006-01-02 15:04:05",
                                   type: 'warning',
-                                  duration: 3000,
+                                  duration: 2000,
                                   offset: 300
                                 });
                                 //alert(v.title+",日期格式错误!正确格式:2006-01-02 15:04:05")
@@ -1084,6 +1128,8 @@
                         v.status = n
                     } else if (n=="2"){
                         v.status = n
+                    }else if (n=="4"){
+                        v.status = n
                     }
                 });
                 two.status = n
@@ -1092,15 +1138,6 @@
                     two: two,
                     type: false
                 })
-                /**
-                 two.content.forEach(function(v) {
-                v.uInput.forEach(function(value) {
-                    if (value.input && value.input != '') {
-                        value.status = n
-                    }
-                })
-            })
-                 */
             },
             saveDataOne:function(one,n){
                 //保存后的样式
@@ -1118,7 +1155,7 @@
                                       this.$message({
                                         message: value.title+",日期格式错误!正确格式:2006-01-02 15:04:05",
                                         type: 'warning',
-                                        duration: 3000,
+                                        duration: 2000,
                                         offset: 300
                                       });
                                         //alert(value.title+",日期格式错误!正确格式:2006-01-02 15:04:05")
@@ -1149,25 +1186,140 @@
                     cancelButtonText: '取消',
                     type: 'warning'
                 }).then(() => {
-                    this.saveData(stype)
+                    this.upChange(stype)
                 }).catch(() => {
                 });
             },
             //保存事件
-            saveData: function() {
-                 $.ajax({
+            upChange: function (stype) {
+                console.log(this.editData, stype)
+                var noTagKey = [];
+                this.editData.filter(function (one) {
+<!--                   console.log("title---",one.title,one.status) -->
+                  if(one.title == "标的信息"||one.title == "多包信息"||one.title == "中标候选人信息"){
+                    if(allCheckFields[one.title] && one.status == -1){
+                      noTagKey.push(one.title);
+                    }
+                  }else{
+                    one.content.filter(function(v) {
+                      v.uInput.filter(function (u) {
+                        if(allCheckFields[u.key] && u.status == -1){
+                          noTagKey.push(u.title);
+                        }
+                      })
+                    })
+                  }
+                })
+                if (noTagKey.length >0){
+                  var fieldText = noTagKey.join(",");
+                  fieldText = fieldText.replace(/\([^\)]*\)/g, "");
+                  this.$alert("未标注信息:"+fieldText);
+                  return
+                }
+                var resultStatus = false
+                if (stype == 1) {//全部字段验证
+                    var checkAllKey = this.editData.filter(function (one) {
+                        var otherOne = one.content.filter(function(v) {
+                            return v.uInput.filter(function (u) {
+                                return u.status == '-1'
+                            }).length
+                        })
+                        if ((one.title=="标的信息"||one.title=="多包信息"||one.title=="中标候选人信息") && (one.status == "-1")) {
+                            return true
+                        } else {
+                            return otherOne.length
+                        }
+                    })
+                    resultStatus = !Boolean(checkAllKey.length)
+                } else {//部分字段验证
+                    var otherTag = 0 //标注状态 0:没标 1:标注成功 2:标注失败
+                    var baseTag = 0
+                    this.editData.filter(function (one) {
+                        //多包信息、中标候选人信息在为标注失败的前提下检测标注状态,一个失败不能保存
+                        if(otherTag < 2){
+                          if (one.title=="标的信息"||one.title=="多包信息"||one.title=="中标候选人信息") {
+                            if (one.status == "-1") {//没标
+                                if(otherTag != 1){//前一个标注成功不用记录后一个是否未标
+                                  otherTag = 0
+                                }
+                            } else {
+                                if (one.content.length === 0) {//不含子包
+                                  if (one.status == '2') {
+                                    otherTag = 2 //失败
+                                  }else{
+                                    otherTag = 1 //成功
+                                  }
+                                }else{//含子包
+                                  if(one.title == "标的信息"){
+                                    var otherOne = one.content.filter(function(v) {
+                                      if(v.status >= 1){//子信息标注
+                                        var twoLength =  v.uInput.filter(function (u) {
+                                            return u.status == '-1'
+                                        })
+                                        if(twoLength.length > 0){
+                                          otherTag = 2
+                                        }
+                                        return true //返回此条信息被标注
+                                      }
+                                    })
+                                    if(otherTag != 2){
+                                      if(otherOne.length > 0){//
+                                        otherTag = 1
+                                      }else{
+                                        otherTag = 2
+                                      }
+                                    }
+                                  }else{
+                                    var otherOne = one.content.filter(function(v) {
+                                      return v.uInput.filter(function (u) {
+                                          return u.status == '-1'
+                                      }).length
+                                    })
+                                    if(otherOne.length > 0){//
+                                      otherTag = 2
+                                    }else{
+                                      otherTag = 1
+                                    }
+                                  }
+                                }
+                            }
+                          } else {
+                            var baseOne = one.content.filter(function(v) {
+                                return v.uInput.filter(function (u) {
+                                    return u.status != '-1'
+                                }).length
+                            })
+                            if (baseOne.length >0){//基本字段
+                              baseTag = 1
+                            }
+                          }
+                        }
+                    })
+                    if(otherTag == 0 && baseTag == 1){
+                      resultStatus = true
+                    }else if (otherTag == 1){
+                      resultStatus = true
+                    }
+                }
+                if (!resultStatus) {
+                    this.$alert("未标注完成");
+                    return
+                }
+                var d= JSON.stringify(this.editData);
+                var _this = this
+                $.ajax({
                     url:"/center/reviewsave",
                     method:"post",
-                    data: {_id:_id},
+                    data: {key:d,_id:_id,stype:stype},
                     success:function(res){
                         if(res){
-                            document.getElementById("com-alert-val").innerHtml="保存成功";
-                            var label1 = document.getElementById("com-alert");
-                            label1.style.display="block";
-                            setTimeout(function(){
-                                    label1.style.display="none";
-                                },
-                                1000)
+                          _this.$message({
+                            message: '保存成功',
+                            type: 'success',
+                            duration: 1000,
+                            offset: 300
+                          });
+                          issave = true//保存成功
                         }
                     },
                     error:function(err){

+ 39 - 6
src/web/templates/review.html

@@ -65,17 +65,41 @@
         </div>
     </div>
 
+    <!-- 通用标签modal -->
+    <div class="modal fade" id="modal-result" 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">
+                        <div class="edit-form">
+                            <div class="edit-info">
+                                <span class="info"><i class="fa fa-fw fa-tags fa-lg"></i>公共标签</span>
+                            </div>
+                            <div class="content">
+                                <table id="result" class="table table-bordered">
+                                    <thead>
+                                    <tr id="tableTitle">
+                                    <th></th>
+                                    </tr>
+                                    </thead>
+                                </table>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div><!-- /.modal -->
+    </div>
 
 </head>
 <body>
 
 <script>
-
+    var fields = {{ .T.fields }}
     $(document).ready(function () {
         $("#user").append("<option value=-1>请选择</option>")
         $("#user").append("<option value=0>全部</option>")
         for(i in {{.T.users}}){
-            console.log({{.T.users}}[i])
             $("#user").append("<option value='"+{{.T.users}}[i]["_id"]+"'>"+{{.T.users}}[i]["_id"]+"</option>")
         }
 
@@ -106,7 +130,7 @@
             "columns": [
                 {"data": null, width:"1%"},
                 {"data": "title", width: "40%", render: function (val, a, row) {
-                        if (row["review"] == 1) {
+                        if (row["re_data"] == 1) {
                             tmp = '<a style="display: inline-block;cursor:pointer;font-size:18px;color: green" onclick="skipDetail(\''+row._id+'\')">'+val+'</a>'
                         }else {
                             tmp = '<a style="display: inline-block;cursor:pointer;font-size:18px;color: #428bca" onclick="skipDetail(\''+row._id+'\')">'+val+'</a>'
@@ -127,6 +151,14 @@
                 }
             }
         })
+
+        console.log({{.T.fields}})
+        for(k in fields){
+//             console.log(k, fields[k], type of(fields[k]))
+//             if fields[k] {
+//                 $('#result').append('<th>' + k + '</th>');
+//             }
+        }
     });
     function findData() {
 
@@ -150,15 +182,16 @@
         window.open("/center/reviewdetail/"+_id+".html");
     }
     function statResult() {
+        $("#modal-result").modal("show");
+        return
          $.ajax({
             url:"/center/review/result",
             type:"get",
             success:function(r){
             if (r.rep) {
-                    $('#dataTable').dataTable().fnClearTable();
-                    $('#dataTable').dataTable().fnAddData(r.data);
+                    $("#modal-result").modal("show");
                 }else {
-                    alert(r.msg)
+                    alert("统计失败!")
                 }
             }
         })