maxiaoshan 3 年之前
父节点
当前提交
842cdbcfcd
共有 5 个文件被更改,包括 558 次插入363 次删除
  1. 33 17
      src/config.json
  2. 306 230
      src/front/front.go
  3. 8 8
      src/main.go
  4. 1 0
      src/util/config.go
  5. 210 108
      src/web/templates/detail.html

+ 33 - 17
src/config.json

@@ -23,6 +23,14 @@
 		"coll2": "extract",
 		"size": 10
     },
+    "fields":{
+    	"projectname": true,
+		"area": true,
+		"projectcode": true,
+		"purchasinglist": true,
+		"package": true,
+		"winnerorder": true
+	},
     "es":{
     	"addr": "http://192.168.3.11:9800",
 	    "index": "bidding",
@@ -55,25 +63,29 @@
                 "key": "district",
                 "descript": "区县(e)"
             },
+            {
+                "key": "buyer",
+                "descript": "采购单位(a)"
+            },
             {
                 "key": "budget",
                 "descript": "预算(z)"
             },
             {
-                "key": "bidamount",
-                "descript": "中标金额(x)"
+                "key": "agency",
+                "descript": "代理机构(s)"
             },
             {
-                "key": "buyer",
-                "descript": "采购单位(a)"
+                "key": "bidamount",
+                "descript": "中标金额(x)"
             },
             {
-                "key": "agency",
-                "descript": "代理机构(s)"
+                "key": "s_winner",
+                "descript": "中标单位(d)"
             },
             {
-                "key": "s_winner",
-                "descript": "s_winner(d)"
+                "key": "bidamounttype",
+                "descript": "金额类型"
             }
         ],
         "timeplace":[
@@ -150,10 +162,6 @@
             {
                 "key": "dimensions",
                 "descript": "尺寸"
-            },
-            {
-                "key": "pclisover",
-                "descript": "标注完全"
             }
         ],
         "package": [
@@ -169,20 +177,32 @@
                 "key": "origin",
                 "descript": "标段(包)编号"
             },
+            {
+                "key": "text",
+                "descript": "标段(包)内容"
+            },
             {
                 "key": "budget",
                 "descript": "标段(包)预算"
             },
+            {
+                "key": "bidamounttype",
+                "descript": "金额类型"
+            },
             {
                 "key": "winner",
                 "descript": "标段(包)中标单位"
             },
             {
                 "key": "bidamount",
-                "descript": "标段(包)中标"
+                "descript": "标段(包)中标金额"
             }
         ],
         "winnerorder": [
+        	{
+                "key": "sortstr",
+                "descript": "候选人名次"
+            },
             {
                 "key": "entname",
                 "descript": "候选人名称"
@@ -190,10 +210,6 @@
             {
                 "key": "price",
                 "descript": "投标报价"
-            },
-            {
-                "key": "sortstr",
-                "descript": "候选人名次"
             }
         ],
         "other": [

+ 306 - 230
src/front/front.go

@@ -3,6 +3,7 @@ package front
 
 import (
 	"math"
+
 	//"container/list"
 	"encoding/json"
 	"fmt"
@@ -205,6 +206,7 @@ func (i *Front) Biaozhu() error {
 		}
 		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 "基本字段":
@@ -212,7 +214,7 @@ func (i *Front) Biaozhu() error {
 		case "时间地点":
 			BzSJDD(content, set, unset, errset)
 		case "标的信息":
-			BzBDXX(content, set, unset, errset, isext, status)
+			BzBDXX(content, set, unset, errset, isext, istag, status)
 		case "多包信息":
 			BzDBXX(content, set, unset, errset, isext, status)
 		case "中标候选人信息":
@@ -231,12 +233,13 @@ func (i *Front) Biaozhu() error {
 				// 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, status)
+				BzBDXX(content, set, unset, errset, isext, istag, status)
 			} else if j == 3 { //多包
 				BzDBXX(content, set, unset, errset, isext, status)
 			} else if j == 4 { //候选人
@@ -246,144 +249,126 @@ func (i *Front) Biaozhu() error {
 			}
 		}
 	}
-	// qu.Debug("errset---", errset)
-	// qu.Debug("set---", set)
-	// qu.Debug("unset---", unset)
+	qu.Debug("errset---", errset)
+	qu.Debug("set---", set)
+	qu.Debug("unset---", unset)
+	userInfo := map[string]interface{}{}     //记录本次标注日志
+	modifyFields := map[string]interface{}{} //本次标注所有字段
+	unerrset := map[string]interface{}{}     //记录errdata错误信息表删除
+
 	loginuser := i.GetSession("loginuser").(string)
-	unerrset := map[string]interface{}{} //记录errdata错误信息表删除
 	coll := i.GetSession("coll").(string)
-	data, _ := util.MgoM.FindById(coll, _id, nil)
-	//标注误操作处理
+	data, _ := util.MgoM.FindById(coll, _id, nil) //查询标注保存前的原始信息
+	modifyuser := qu.ObjToString((*data)["modifyuser"])
+	//标注多次操作处理
 	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:] //去除前缀,获得字段
-				if s == preKey+"package" || s == preKey+"purchasinglist" || s == preKey+"winnerorder" {
-					if (*data)[s] != nil { //package、purchasinglist、winnerorder已标注,不再修改
-						delete(set, s)
-						delete(set, field)
-						continue
-					}
-				}
-				if set[field] == nil && status != 4 { //表示该字段没有要修改的值,此时标记为1或4(亦或是ck_wodrisext;ck_pkgisext;ck_pclisext)
+			if strings.HasPrefix(s, preKey) {
+				status := qu.IntAll(sv)                                        //标注字段状态
+				field := s[3:]                                                 //去除前缀,被标注字段
+				checkedStatus := qu.IntAll((*data)[s])                         //数据库被标注状态
+				if status == 1 && (checkedStatus == 2 || checkedStatus == 1) { //数据库已有标记,且页面标注正确,此次该字段不做标注保存
+					qu.Debug("已标注字段field---", field)
+					delete(set, field)
+					delete(set, s)
 					continue
-				} else { //此时有修改的值和标记2、3、4
-					if checkedStatus := qu.IntAll((*data)[s]); checkedStatus != 0 { //已有标注信息的状态
-						if status == 2 && checkedStatus == 4 { //4>2,errdata删除,marked新增该字段,标记变为1
-							unerrset[field] = ""
-							set[s] = 1
-						} else if status == 3 {
-							if checkedStatus == 2 { //2>3,marked 修改该字段,标记变为2
-								set[s] = 2
-							} else if checkedStatus == 3 { //3>3,对比errdata错误值:相等变为1,errdata删除;不等变为3,marked修改该字段
-								errdata, _ := util.MgoM.FindById(util.Config.Totablel, _id, `{"`+field+`":1}`)
+				} else {
+					qu.Debug("未标注字段field---", field, status)
+					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 field == "package" || field == "purchasinglist" || field == "winnerorder" {
+								//}
 								if errdata != nil && len(*errdata) != 0 {
+									qu.Debug(field, (*errdata)[field] != nil, fmt.Sprint((*errdata)[field]))
+									delete(errset, field) //errdata中有该字段的错误记录,不再更新errdata
+									//对比errdata错误值:相等变为1,errdata删除;不等变为2,标注表修改该字段
 									errText := fmt.Sprint((*errdata)[field])
 									text := fmt.Sprint(set[field])
+									qu.Debug("errText---", errText, text)
 									if errText == text {
-										set[s] = 1
-										unerrset[field] = ""
+										set[s] = 1           //更新标注表字段状态
+										unerrset[field] = "" //删除errdata表字段
+										//delete(errset, field)
 									}
 								}
 							}
-						} else if status == 4 {
-							if checkedStatus == 2 { //2>4,errdata删除,marked删除该字段,标记变为1
-								unerrset[field] = ""
-								set[s] = 1
-								unset[field] = ""
-							} else if checkedStatus == 3 { //3>4,marked删除该字段,标记变为4
-								set[s] = 4
-								unset[field] = ""
-							}
 						}
 					}
 				}
 			}
 		}
 	}
+	qu.Debug("errset---", errset)
+	qu.Debug("set---", set)
+	qu.Debug("unset---", unset)
+	qu.Debug("unerrset---", unerrset)
+	//1、errdata操作
 	//存储原错误信息
-	errUpdata := map[string]interface{}{}
-	if len(errset) > 0 {
-		for f, v := range errset {
-			if (*data)[preKey+f] != nil { //已标注保存过不再记录错误信息
-				delete(errset, f)
-				continue
-			}
-			// if ck, ok := (*data)[preKey+f].(int32); ok && ck != 1 { //已标注保存过不再记录错误信息
-			// 	delete(errset, f)
-			// 	continue
-			// }
-			if f == "purchasinglist" || f == "winnerorder" {
-				pcl, _ := (*data)[f].([]interface{})
-				pcl_err := v.([]interface{})
-				for j, perr := range pcl_err {
-					perrMap := perr.(map[string]interface{})
-					if len(perrMap) > 0 {
-						for k, status := range perrMap {
-							if pMap, ok := pcl[j].(map[string]interface{}); ok && len(pMap) > 0 { //避免手动增加的子包找不到原数据
-								pMap[preErr+k] = status //打上错误标记
-								pMap[k] = pMap[k]
-							}
-						}
-					}
-				}
-				errset[f] = (*data)[f]
-			} else if f == "package" {
-				pkg_err, _ := v.(map[string]interface{})
-				pkg := (*data)["package"].(map[string]interface{})
-				for num, v := range pkg_err {
-					result_err := map[string]interface{}{}
-					vMap := v.(map[string]interface{})
-					for k, status := range vMap {
-						if pMap, ok := pkg[num].(map[string]interface{}); ok && len(pMap) > 0 {
-							result_err[preErr+k] = status
-							result_err[k] = pMap[k]
-						}
-					}
-					pkg_err[num] = result_err
-				}
-			} else {
-				errset[f] = (*data)[f]
-			}
-		}
-		//qu.Debug("errset---", errset)
-		if len(errset) > 0 {
-			errset["updatetime"] = time.Now().Unix()
-			errset["modifyuser"] = loginuser
-			errUpdata["$set"] = errset
+	errUpdata := map[string]interface{}{} //errdata所有要更新内容
+	for f, v := range errset {
+		qu.Debug("err filed---", f, v)
+		//if f != "package" && f != "purchasinglist" && f != "winnerorder" {
+		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,
+			},
 		}
-
+	}
+	qu.Debug("set---", set)
+	qu.Debug("errset---", errset)
+	qu.Debug("unerrset---", unerrset)
+	qu.Debug("userInfo---", userInfo)
+	if len(errset) > 0 {
+		errUpdata["$set"] = errset
 	}
 	if len(unerrset) > 0 {
-		//qu.Debug("unerrset---", unerrset)
 		errUpdata["$unset"] = unerrset
 	}
 	if len(errUpdata) > 0 {
 		util.MgoM.Update(util.Config.Totablel, `{"_id":"`+_id+`"}`, errUpdata, true, false)
 	}
+	//更新表操作
 	//qu.Debug("set---", set)
 	//更新正确信息
 	update := map[string]interface{}{}
 	if len(set) > 0 {
 		set["ck_data"] = stype
 		set["updatetime"] = time.Now().Unix()
-		set["modifyuser"] = loginuser
+		if modifyuser == "" {
+			set["modifyuser"] = modifyuser
+		}
 		update["$set"] = set
 	}
+	qu.Debug("unset---", unset)
 	if len(unset) > 0 {
 		update["$unset"] = unset
 	}
+	qu.Debug("update---", update)
 	if len(update) > 0 {
 		b = util.MgoM.Update(coll, `{"_id":"`+_id+`"}`, update, false, false)
 		if b {
-			//for e := IdList.Front(); e != nil; e = e.Next() { //遍历IdList,删除元素
-			//	if _id == qu.ObjToString(e.Value) {
-			//		IdList.Remove(e)
-			//		break
-			//	}
-			//}
 			if coll != util.Config.Fromtable && isSaveMarked { //util.coll此时的标注表  util.Config.Fromtable默认标注表
 				data, _ := util.MgoM.FindById(coll, _id, nil)
 				if data != nil && len(*data) > 0 {
@@ -398,6 +383,8 @@ func (i *Front) Biaozhu() error {
 			}
 		}
 		i.ServeJson(b)
+	} else {
+		i.ServeJson(true)
 	}
 
 	return nil
@@ -431,9 +418,10 @@ func (i *Front) Detail(id string) error {
 	i.T["worder"] = rep["worder"]
 	i.T["packs"] = rep["packs"]
 	i.T["packskey"] = rep["packskey"]
-	i.T["ck_pclisext"] = rep["ck_pclisext"]
-	i.T["ck_wodrisext"] = rep["ck_wodrisext"]
-	i.T["ck_pkgisext"] = rep["ck_pkgisext"]
+	//i.T["ck_pclisext"] = rep["ck_pclisext"]
+	i.T["ck_pclistag"] = rep["ck_pclistag"]
+	//i.T["ck_wodrisext"] = rep["ck_wodrisext"]
+	//i.T["ck_pkgisext"] = rep["ck_pkgisext"]
 	i.T["timeplace"] = rep["timeplace"]
 	i.T["purchasinglist"] = rep["purchasinglist"]
 	i.T["other"] = rep["other"]
@@ -451,6 +439,7 @@ func (i *Front) Detail(id string) error {
 	checkedNum, allNum := GetCheckedAndAllDataInfo(query, coll) //已标和总数信息
 	i.T["checkednum"] = checkedNum
 	i.T["allnum"] = allNum
+	i.T["fields"] = util.Config.Fields
 	//存入Redis
 	redis.Put("extcheck", coll+"_"+id, "", util.Config.RedisTimeout*60) //正在标注的数据存入redis避免多人同时标注(加上coll左前缀避免不同表相同id数据不能同时标注)
 	return i.Render("detail.html", &i.T)
@@ -762,12 +751,14 @@ func getDetail(id, coll string) map[string]interface{} {
 	// 	}
 	// }
 	info["_id"] = mgo.BsonIdToSId(info["_id"])
-	ck_pclisext, _ := info["ck_pclisext"].(bool)
-	ck_wodrisext, _ := info["ck_wodrisext"].(bool)
-	ck_pkgisext, _ := info["ck_pkgisext"].(bool)
-	rep["ck_pclisext"] = ck_pclisext
-	rep["ck_wodrisext"] = ck_wodrisext
-	rep["ck_pkgisext"] = ck_pkgisext
+	//ck_pclisext, _ := info["ck_pclisext"].(bool)
+	ck_pclistag, _ := info["ck_pclistag"].(bool)
+	//ck_wodrisext, _ := info["ck_wodrisext"].(bool)
+	//ck_pkgisext, _ := info["ck_pkgisext"].(bool)
+	//rep["ck_pclisext"] = ck_pclisext
+	rep["ck_pclistag"] = ck_pclistag
+	//rep["ck_wodrisext"] = ck_wodrisext
+	//rep["ck_pkgisext"] = ck_pkgisext
 	href := qu.ObjToString(info["href"])
 	if !strings.HasPrefix(href, "http") {
 		info["href"] = "http://" + href
@@ -784,9 +775,9 @@ func getDetail(id, coll string) map[string]interface{} {
 	rep["packs"] = packs
 	rep["packskey"] = packskey
 	rep["pkg_new"] = pkg_new
-	purchasinglist, pcl_new := setPurchasingMap(info) //标的物
+	purchasinglist, isNewStatus := setPurchasingMap(info) //标的物
 	rep["purchasinglist"] = purchasinglist
-	rep["pcl_new"] = pcl_new
+	rep["pcl_new"] = isNewStatus
 	worder, worder_new := setWorderMap(info) //中标候选人
 	rep["worder"] = worder
 	rep["worder_new"] = worder_new
@@ -912,28 +903,33 @@ func DealData(tmpLen int, publishtime float64, tmp []map[string]interface{}, mor
 }
 
 //拼装中标候选人
-func setWorderMap(info map[string]interface{}) ([]interface{}, []bool) {
+func setWorderMap(info map[string]interface{}) ([]interface{}, []map[string]interface{}) {
 	//基本参数--中标候选人
 	winnerorder, _ := util.Config.Biaozhu["winnerorder"].([]interface{})
 	worders := []interface{}{}
-	isNewWorder := []bool{} //记录子包是否是新增的
+	isNewAndStatus := []map[string]interface{}{}
 	if tmpwds, ok := info["winnerorder"].([]interface{}); ok {
 		for _, v := range tmpwds {
 			if wd, ok := v.(map[string]interface{}); ok {
-				isNew, _ := wd["ck_isnew"].(bool)
-				isNewWorder = append(isNewWorder, isNew)
+				//isNew, _ := wd["ck_isnew"].(bool)
+				isNew := false
+				status := "-1"
+				if wd["ck_winnerorder"] != nil {
+					status = "1"
+				}
+				isNewAndStatus = append(isNewAndStatus, map[string]interface{}{"isnew": isNew, "status": status})
 				wds := []interface{}{}
 				for _, cp := range winnerorder {
 					cp, _ := cp.(map[string]interface{})
+					value := wd[qu.ObjToString(cp["key"])]
+					if value == nil {
+						value = ""
+					}
 					tp := map[string]interface{}{
 						"key":      cp["key"],
 						"descript": cp["descript"],
-						"value":    wd[qu.ObjToString(cp["key"])],
-					}
-					if wd[preKey+fmt.Sprint(tp["key"])] == nil {
-						tp["status"] = "-1"
-					} else {
-						tp["status"] = "1"
+						"value":    value,
+						"status":   status,
 					}
 					wds = append(wds, tp)
 				}
@@ -941,19 +937,26 @@ func setWorderMap(info map[string]interface{}) ([]interface{}, []bool) {
 			}
 		}
 	}
-	return worders, isNewWorder
+	return worders, isNewAndStatus
 }
 
 //拼装标的物
-func setPurchasingMap(info map[string]interface{}) ([]interface{}, []bool) {
+func setPurchasingMap(info map[string]interface{}) ([]interface{}, []map[string]interface{}) {
 	purchasinglist, _ := util.Config.Biaozhu["purchasinglist"].([]interface{})
 	purchasinglists := []interface{}{}
-	isNewPcl := []bool{} //记录子包是否是新增的
+	//isNewPcl := []bool{} //记录子包是否是新增的
+	isNewAndStatus := []map[string]interface{}{}
 	if tmpcls, ok := info["purchasinglist"].([]interface{}); ok {
 		for _, v := range tmpcls {
 			if pcl, ok := v.(map[string]interface{}); ok {
-				isNew, _ := pcl["ck_isnew"].(bool)
-				isNewPcl = append(isNewPcl, isNew)
+				//isNew, _ := pcl["ck_isnew"].(bool)
+				isNew := false
+				status := "-1"
+				if pcl["ck_purchasinglist"] != nil {
+					status = "1"
+				}
+				//isNewPcl = append(isNewPcl, isNew)
+				isNewAndStatus = append(isNewAndStatus, map[string]interface{}{"isnew": isNew, "status": status})
 				pcls := []interface{}{}
 				for _, ps := range purchasinglist {
 					ps, _ := ps.(map[string]interface{})
@@ -965,23 +968,24 @@ func setPurchasingMap(info map[string]interface{}) ([]interface{}, []bool) {
 						"key":      ps["key"],
 						"descript": ps["descript"],
 						"value":    value,
+						"status":   status,
 					}
-					if pcl[preKey+fmt.Sprint(tp["key"])] == nil {
-						tp["status"] = "-1"
-					} else {
-						tp["status"] = "1"
-					}
+					// if pcl[preKey+fmt.Sprint(tp["key"])] == nil {
+					// 	tp["status"] = "-1"
+					// } else {
+					// 	tp["status"] = "1"
+					// }
 					pcls = append(pcls, tp)
 				}
 				purchasinglists = append(purchasinglists, pcls)
 			}
 		}
 	}
-	return purchasinglists, isNewPcl
+	return purchasinglists, isNewAndStatus
 }
 
 //拼装子包信息
-func setPaceMap(info map[string]interface{}) ([]map[string]interface{}, []string, map[string]bool) {
+func setPaceMap(info map[string]interface{}) ([]map[string]interface{}, []string, []bool) {
 	var confpack []interface{}
 	confpack, _ = util.Config.Biaozhu["package"].([]interface{})
 	packs := map[string]map[string]interface{}{}
@@ -990,7 +994,12 @@ func setPaceMap(info map[string]interface{}) ([]map[string]interface{}, []string
 	if packages, ok := info["package"].(map[string]interface{}); ok && len(packages) > 0 {
 		for k, tmpackage := range packages { //遍历分包
 			if tmppack, ok := tmpackage.(map[string]interface{}); ok {
-				isNew, _ := tmppack["ck_isnew"].(bool)
+				//isNew, _ := tmppack["ck_isnew"].(bool)
+				isNew := false
+				status := "-1"
+				if tmppack["ck_package"] != nil {
+					status = "1"
+				}
 				isNewPkg[k] = isNew
 				sortpackskey = append(sortpackskey, k)
 				pack := []interface{}{}
@@ -1009,20 +1018,12 @@ func setPaceMap(info map[string]interface{}) ([]map[string]interface{}, []string
 					} else {
 						tp["value"] = ""
 					}
-					if tmppack[preKey+fmt.Sprint(tp["key"])] == nil {
-						tp["status"] = "-1"
-					} else {
-						tp["status"] = "1"
-					}
+					tp["status"] = status
 					pack = append(pack, tp)
 				}
 				//特殊处理中标单位和中标金额
 				winnerall := []interface{}{}
 				if tmpWinnerAll, ok := tmppack["winner_all"].([]interface{}); ok && len(tmpWinnerAll) > 0 {
-					status := "-1"
-					if tmppack[preKey+"winner_all"] != nil {
-						status = "1"
-					}
 					for _, tmp := range tmpWinnerAll {
 						tmpMap := tmp.(map[string]interface{})
 						win := map[string]interface{}{
@@ -1039,7 +1040,7 @@ func setPaceMap(info map[string]interface{}) ([]map[string]interface{}, []string
 							bidamount = fmt.Sprint(tmpMap["bidamount"])
 						}
 						bid := map[string]interface{}{
-							"descript": "标段(包)中金额",
+							"descript": "标段(包)中金额",
 							"key":      "bidamount",
 							"status":   status,
 							"value":    bidamount,
@@ -1054,25 +1055,28 @@ func setPaceMap(info map[string]interface{}) ([]map[string]interface{}, []string
 						"value":    "",
 					})
 					winnerall = append(winnerall, map[string]interface{}{
-						"descript": "标段(包)中标",
+						"descript": "标段(包)中标金额",
 						"key":      "bidamount",
 						"status":   "-1",
 						"value":    "",
 					})
 				}
 				packs[k] = map[string]interface{}{
-					"pack":      pack,
-					"winnerall": winnerall,
+					"pack":       pack,
+					"packstatus": status,
+					"winnerall":  winnerall,
 				}
 			}
 		}
 	}
 	sort.Strings(sortpackskey)
 	packages := []map[string]interface{}{}
+	isNewPkgArr := []bool{}
 	for _, v := range sortpackskey {
 		packages = append(packages, packs[v])
+		isNewPkgArr = append(isNewPkgArr, isNewPkg[v])
 	}
-	return packages, sortpackskey, isNewPkg
+	return packages, sortpackskey, isNewPkgArr
 }
 
 //拼装抽取common值
@@ -1171,26 +1175,31 @@ func BzJBZD(content []interface{}, set, unset, errset map[string]interface{}) {
 						continue
 					}
 					if status == 2 || status == 3 { //新增、修改
-						input := tmpMap["input"]                                                                     //值
-						if key == "subtype" || key == "attach_discern" || key == "attach_ext" || key == "isrepeat" { //附件识别、抽取select
+						input := tmpMap["input"]                                                                                               //值
+						if key == "bidamounttype" || key == "subtype" || key == "attach_discern" || key == "attach_ext" || key == "isrepeat" { //附件识别、抽取select
 							input = tmpMap["select"]
-						} else if key == "budget" || key == "bidamount" || key == "biddiscount" {
-							input = qu.Float64All(input)
 						}
-						if key == "subtype" {
-							if topsubtype := strings.Split(qu.ObjToString(input), "-"); len(topsubtype) == 2 {
-								set["toptype"] = topsubtype[0]
-								set[key] = topsubtype[1]
-							}
+						if input == "" {
+							unset[key] = "" //表示删除
 						} else {
-							set[key] = input
+							if key == "budget" || key == "bidamount" || key == "biddiscount" {
+								input = qu.Float64All(input)
+							}
+							if key == "subtype" {
+								if topsubtype := strings.Split(qu.ObjToString(input), "-"); len(topsubtype) == 2 {
+									set["toptype"] = topsubtype[0]
+									set[key] = topsubtype[1]
+								}
+							} else {
+								set[key] = input
+							}
 						}
 						errset[key] = status
 					} else if status == 4 { //删除
 						unset[key] = ""
 						errset[key] = status
 					}
-					set[preKey+key] = status
+					set[preKey+key] = status //记录状态
 				}
 			}
 		}
@@ -1209,13 +1218,17 @@ func BzSJDD(content []interface{}, set, unset, errset map[string]interface{}) {
 					key := qu.ObjToString(tmpMap["key"]) //字段
 					if status == 2 || status == 3 {      //新增、修改
 						input := tmpMap["input"] //值
-						if key == "bidopentime" || key == "publishtime" || key == "bidendtime" || key == "project_startdate" || key == "project_completedate" {
-							inputTmp, _ := time.ParseInLocation(qu.Date_Full_Layout, input.(string), time.Local)
-							input = inputTmp.Unix()
-						} else if key == "project_duration" {
-							input = qu.IntAll(input)
+						if input == "" {
+							unset[key] = ""
+						} else {
+							if key == "bidopentime" || key == "publishtime" || key == "bidendtime" || key == "project_startdate" || key == "project_completedate" {
+								inputTmp, _ := time.ParseInLocation(qu.Date_Full_Layout, input.(string), time.Local)
+								input = inputTmp.Unix()
+							} else if key == "project_duration" {
+								input = qu.IntAll(input)
+							}
+							set[key] = input
 						}
-						set[key] = input
 						errset[key] = status
 					} else if status == 4 { //删除
 						unset[key] = ""
@@ -1231,14 +1244,14 @@ func BzSJDD(content []interface{}, set, unset, errset map[string]interface{}) {
 }
 
 //标注标的信息
-func BzBDXX(content []interface{}, set, unset, errset map[string]interface{}, isext bool, status int) {
+func BzBDXX(content []interface{}, set, unset, errset map[string]interface{}, isext, istag bool, status int) {
 	//qu.Debug("是否抽取:", status, isext, len(content), errset)
 	if status == -1 {
 		return
 	}
-	set["ck_pclisext"] = isext //标的信息是否抽取标记
+	//set["ck_pclisext"] = isext //标的信息是否抽取标记
+	set["ck_pclistag"] = istag //标的信息是否标注完全
 	purchasinglist := []interface{}{}
-	errList := []interface{}{}
 	delpclson := 0
 	for _, con := range content {
 		info, _ := con.(map[string]interface{})
@@ -1251,43 +1264,50 @@ func BzBDXX(content []interface{}, set, unset, errset map[string]interface{}, is
 			result := map[string]interface{}{
 				"ck_isnew": isNew,
 			}
-			errResult := map[string]interface{}{}
 			for _, tmp := range uInputs {
 				if tmpMap, ok := tmp.(map[string]interface{}); ok {
 					key := qu.ObjToString(tmpMap["key"]) //字段
 					input := tmpMap["input"]             //值
-					status := qu.IntAll(tmpMap["status"])
+					//status := qu.IntAll(tmpMap["status"])
 					isNull := false
-					if key == "number" || key == "unitprice" || key == "totalprice" {
-						if input != "" { //有值
-							isNull = false
-							input = qu.Float64All(input)
-						} else {
-							isNull = true
-						}
-					} else if key == "pclisover" {
-						input = tmpMap["select"]
+					if input == "" { //判断前台页面是否填值,无值不进行字段存储
+						isNull = true
+					} else if key == "number" || key == "unitprice" || key == "totalprice" {
+						input = qu.Float64All(input)
 					}
 					if !isNull { //避免数字类型的字段在没有填写值的情况默认给0
 						result[key] = input
 					}
-					result[preKey+key] = status
-					if !isNew && (status == 2 || status == 3 || status == 4) {
-						errResult[key] = status //记录哪个字段错误
-					}
+					//result[preKey+key] = status
+					// if !isNew && (status == 2 || status == 3 || status == 4) {
+					// 	errResult[key] = status //记录哪个字段错误
+					// }
 				}
 			}
+			if pclSonStatus != -1 { //没有标注的标的信息不打标记
+				result["ck_purchasinglist"] = pclSonStatus
+			}
 			if len(result) > 0 && pclSonStatus != 4 {
 				purchasinglist = append(purchasinglist, result)
 			}
-			errList = append(errList, errResult)
 		}
 	}
-	errset["purchasinglist"] = errList
+	if status != 1 { //如果purchasinglist状态不是1,errdata则记录原purchasinglist字段
+		errset["purchasinglist"] = true
+	}
+	qu.Debug("purchasinglist", len(purchasinglist))
 	if len(purchasinglist)+delpclson == len(content) {
-		set["purchasinglist"] = purchasinglist
+		if len(purchasinglist) > 0 {
+			set["purchasinglist"] = purchasinglist
+		}
 		set[preKey+"purchasinglist"] = status
+		if len(content) > 0 && delpclson == len(content) { //只有删除
+			unset["purchasinglist"] = ""
+		}
 	}
+	qu.Debug("set---", set)
+	qu.Debug("errset---", errset)
+	qu.Debug("unset---", unset)
 }
 
 //标注多包信息
@@ -1296,9 +1316,9 @@ func BzDBXX(content []interface{}, set, unset, errset map[string]interface{}, is
 	if status == -1 {
 		return
 	}
-	set["ck_pkgisext"] = isext //多包是否抽取标记
+	//set["ck_pkgisext"] = isext //多包是否抽取标记
 	pkgs := map[string]interface{}{}
-	errMap := map[string]interface{}{}
+	//errMap := map[string]interface{}{}
 	newNum := 1
 	delpkgson := 0 //记录子包删除个数
 	for _, con := range content {
@@ -1317,47 +1337,95 @@ func BzDBXX(content []interface{}, set, unset, errset map[string]interface{}, is
 			result := map[string]interface{}{
 				"ck_isnew": isNew,
 			}
-			errResult := map[string]interface{}{}
+			//errResult := map[string]interface{}{}
+			winnerArr := []interface{}{}
+			bidamountArr := []interface{}{}
 			for _, tmp := range uInputs {
 				if tmpMap, ok := tmp.(map[string]interface{}); ok {
 					key := qu.ObjToString(tmpMap["key"]) //字段
 					input := tmpMap["input"]             //值
-					status := qu.IntAll(tmpMap["status"])
-					isNull := false
-					if key == "bidamount" || key == "budget" {
-						if input != "" { //有值
-							isNull = false
+					//status := qu.IntAll(tmpMap["status"])
+					isNull := false //记录字段是否有值
+					if key == "bidamounttype" {
+						input = tmpMap["select"]
+					} else {
+						if input == "" { //判断前台页面是否填值,无值不进行字段存储
+							isNull = true
+						} else if key == "bidamount" || key == "budget" {
 							input = qu.Float64All(input)
+						}
+					}
+					if key == "winner" {
+						if isNull {
+							winnerArr = append(winnerArr, nil)
 						} else {
-							isNull = true
+							winnerArr = append(winnerArr, input)
 						}
+						continue
+					} else if key == "bidamount" {
+						if isNull {
+							bidamountArr = append(bidamountArr, nil)
+						} else {
+							bidamountArr = append(bidamountArr, input)
+						}
+						continue
 					}
+
 					if !isNull { //避免数字类型的字段在没有填写值的情况默认给0
 						result[key] = input
 					}
-					result[preKey+key] = status
-					if !isNew && (status == 2 || status == 3 || status == 4) {
-						errResult[key] = status //记录哪个字段错误
+					//result[preKey+key] = status
+					// if !isNew && status >= 2 {
+					// 	errResult[key] = status //记录哪个字段错误
+					// }
+				}
+			}
+			winner_all := []interface{}{}
+			if len(winnerArr) == len(bidamountArr) {
+				for i, w := range winnerArr {
+					b := bidamountArr[i]
+					wbMap := map[string]interface{}{}
+					if w != nil {
+						wbMap["winner"] = w
+					}
+					if b != nil {
+						wbMap["bidamount"] = b
+					}
+					if len(wbMap) > 0 {
+						winner_all = append(winner_all, wbMap)
 					}
 				}
 			}
-			if len(errResult) > 0 {
-				errMap[num] = errResult
+			if len(winner_all) > 0 {
+				result["winner_all"] = winner_all
 			}
+			result["ck_package"] = pkgSonStatus
+			// if len(errResult) > 0 {
+			// 	errMap[num] = errResult
+			// }
 			if len(result) > 0 && pkgSonStatus != 4 { //要删除的子包不再保存
 				pkgs[num] = result
 			}
 		}
 	}
-	if len(errMap) > 0 {
-		errset["package"] = errMap
+	if status != 1 { //如果package状态不是1,errdata则记录原package字段
+		errset["package"] = true
 	}
+	// if len(errMap) > 0 {
+	// 	errset["package"] = errMap
+	// }
+	qu.Debug("pkgs", len(pkgs))
 	if len(pkgs)+delpkgson == len(content) {
-		set["package"] = pkgs
+		if len(pkgs) > 0 {
+			set["package"] = pkgs
+		}
 		set[preKey+"package"] = status
+		if len(content) > 0 && delpkgson == len(content) { //只有删除
+			unset["package"] = ""
+		}
 	}
 	// qu.Debug("set---", set)
-	// qu.Debug("unset---", unset)
+	// qu.Debug("errset---", errset)
 }
 
 //标注中标候选人信息
@@ -1366,9 +1434,8 @@ func BzZBHXRXX(content []interface{}, set, unset, errset map[string]interface{},
 	if status == -1 {
 		return
 	}
-	set["ck_wodrisext"] = isext //中标候选人是否抽取标记
+	//set["ck_wodrisext"] = isext //中标候选人是否抽取标记
 	winnerorder := []interface{}{}
-	errList := []interface{}{}
 	delwodrson := 0
 	for _, con := range content {
 		info, _ := con.(map[string]interface{})
@@ -1381,44 +1448,47 @@ func BzZBHXRXX(content []interface{}, set, unset, errset map[string]interface{},
 			result := map[string]interface{}{
 				"ck_isnew": isNew,
 			}
-			errResult := map[string]interface{}{}
 			for _, tmp := range uInputs {
 				if tmpMap, ok := tmp.(map[string]interface{}); ok {
 					key := qu.ObjToString(tmpMap["key"]) //字段
 					input := tmpMap["input"]             //值
-					status := qu.IntAll(tmpMap["status"])
 					isNull := false
-					if key == "price" {
-						if input != "" { //有值
-							isNull = false
-							input = qu.Float64All(input)
-						} else {
-							isNull = true
-						}
+					if input == "" { //判断前台页面是否填值,无值不进行字段存储
+						isNull = true
+					} else if key == "price" {
+						input = qu.Float64All(input)
 					}
 					if !isNull { //避免数字类型的字段在没有填写值的情况默认给0
 						result[key] = input
 					}
-					result[preKey+key] = status
-					if !isNew && (status == 2 || status == 3 || status == 4) {
-						errResult[key] = status //记录哪个字段错误
-					}
+					result["ck_winnerorder"] = wodrSonStatus
+					// result[preKey+key] = status
+					// if !isNew && (status == 2 || status == 3 || status == 4) {
+					// 	errResult[key] = status //记录哪个字段错误
+					// }
 				}
 			}
 			if len(result) > 0 && wodrSonStatus != 4 {
 				winnerorder = append(winnerorder, result)
 			}
-			errList = append(errList, errResult)
 		}
 	}
-	errset["winnerorder"] = errList
+	if status != 1 { //如果winnerorder状态不是1,errdata则记录原winnerorder字段
+		errset["winnerorder"] = true
+	}
+	qu.Debug("winnerorder", len(winnerorder))
 	if len(winnerorder)+delwodrson == len(content) {
-		set["winnerorder"] = winnerorder
+		if len(winnerorder) > 0 {
+			set["winnerorder"] = winnerorder
+		}
 		set[preKey+"winnerorder"] = status
+		if len(content) > 0 && delwodrson == len(content) { //只有删除
+			unset["winnerorder"] = ""
+		}
 	}
-	// qu.Debug("set---", set)
-	// qu.Debug("unset---", unset)
-	// qu.Debug("errset---", errset)
+	qu.Debug("set---", set)
+	qu.Debug("unset---", unset)
+	qu.Debug("errset---", errset)
 }
 
 //标注其余信息
@@ -1429,17 +1499,23 @@ func BzQYXX(content []interface{}, set, unset, errset map[string]interface{}) {
 			if tmpMap, ok := tmp.(map[string]interface{}); ok {
 				if status := qu.IntAll(tmpMap["status"]); status != -1 {
 					key := qu.ObjToString(tmpMap["key"]) //字段
-					if status == 2 || status == 3 {      //新增、修改
+					qu.Debug(key, "-----", status)
+					if status == 2 || status == 3 { //新增、修改
 						input := tmpMap["input"] //值
 						if key == "isppp" || key == "contract_guarantee" || key == "bid_guarantee" {
 							input = tmpMap["select"]
-						} else if key == "signaturedate" { //
-							inputTmp, _ := time.ParseInLocation(qu.Date_Full_Layout, input.(string), time.Local)
-							input = inputTmp.Unix()
-						} else if key == "bid_bond" || key == "contract_bond" || key == "supervisorrate" || key == "agencyrate" || key == "docamount" || key == "agencyfee" {
-							input = qu.Float64All(input)
 						}
-						set[key] = input
+						if input == "" {
+							unset[key] = ""
+						} else {
+							if key == "signaturedate" { //
+								inputTmp, _ := time.ParseInLocation(qu.Date_Full_Layout, input.(string), time.Local)
+								input = inputTmp.Unix()
+							} else if key == "bid_bond" || key == "contract_bond" || key == "supervisorrate" || key == "agencyrate" || key == "docamount" || key == "agencyfee" {
+								input = qu.Float64All(input)
+							}
+							set[key] = input
+						}
 						errset[key] = status
 					} else if status == 4 { //删除
 						unset[key] = ""

+ 8 - 8
src/main.go

@@ -2,26 +2,26 @@
 package main
 
 import (
-	"crypto/md5"
-	"encoding/hex"
+	//"crypto/md5"
+	//"encoding/hex"
 	_ "filter"
 	"front"
 	"log"
+
 	"qfw/util/redis"
 	"time"
 
 	qu "qfw/util"
-	"strings"
 	"util"
 
 	"github.com/go-xweb/xweb"
 )
 
-func MD5(appid, t, secret string) string {
-	h := md5.New()
-	h.Write([]byte(appid + t + secret))
-	return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
-}
+// func MD5(appid, t, secret string) string {
+// 	h := md5.New()
+// 	h.Write([]byte(appid + t + secret))
+// 	return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
+// }
 func init() {
 	//log.Println(MD5("jynw166_fEs2021", "1617340065", "Tgb#8diO90L"))
 	//os.Exit(0)

+ 1 - 0
src/util/config.go

@@ -27,6 +27,7 @@ type config struct {
 	Elas          map[string]interface{} `json:"es"`
 	TopSubType    map[string]interface{} `json:"topsubtype"`
 	CustomerField map[string]string      `json:"customerfield"`
+	Fields        map[string]bool        `json:"fields"`
 }
 
 const JYHREFPRE = "https://www.jianyu360.cn/article/content/"

+ 210 - 108
src/web/templates/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,9 +171,9 @@
                       </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%">
@@ -170,10 +193,15 @@
                     <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>
@@ -205,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>
@@ -329,6 +357,7 @@
 
 </body>
 <script>
+  var allCheckFields  = {{.T.fields}};//本次需标注的所有字段
   // 页面数据
   var pageDataMap = {
     '原文': {
@@ -344,10 +373,8 @@
   }
   // 更多关联信息
   var moreInfo = {{.T.moreInfo}}
-  console.log(moreInfo)
   //公告关联信息
   var otherInfo = {{.T.otherInfo}};
-  console.log(otherInfo)
   //快捷键
   $(document).keydown(function(event){
     if(!event.shiftKey) {
@@ -386,25 +413,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{
@@ -440,7 +467,7 @@
       //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;
   }
   
@@ -448,7 +475,6 @@
     var issave = false;
     var _id = {{.T.info._id}};
     var nextid = {{.T.nextid}};
-    //console.log(nextid)
     //基本信息
     var common={{.T.common}};
     var uInput=[];
@@ -474,6 +500,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
     }
     //时间地点
@@ -521,9 +552,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
     }
@@ -540,19 +571,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
     }
@@ -578,10 +609,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={}
@@ -594,7 +630,7 @@
         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];
@@ -612,10 +648,10 @@
               status:"2",
               title:pclf[i][key]
           }
-          if(key== "pclisover"){
-            tempNode.select= '是'
-            tempNode.selectArr=['是','否']
-          }
+          //if(key== "pclisover"){
+          //  tempNode.select= '是'
+          //  tempNode.selectArr=['是','否']
+          //}
           pclfInput.push(tempNode)
       }
     }
@@ -637,12 +673,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({
@@ -650,6 +691,7 @@
         delimiters:["[[","]]"],
         data: {
             activeLabel: '原文',
+            nowLabel: ['原文'],
             otherInfo: otherInfo,
             moreInfo: moreInfo,
             scrollCache: {
@@ -693,7 +735,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
                 },
@@ -701,7 +744,7 @@
                     title: '多包信息',
                     show: false,
                     showCheck: true,
-                    checkType: {{.T.ck_pkgisext}},
+                    //checkType: {{.T.ck_pkgisext}},
                     status: {{.T.ck_package}},
                     content: p_content
                 },
@@ -709,7 +752,7 @@
                     title: '中标候选人信息',
                     show: false,
                     showCheck: true,
-                    checkType: {{.T.ck_wodrisext}},
+                    //checkType: {{.T.ck_wodrisext}},
                     status: {{.T.ck_winnerorder}},
                     content: c_content
                 },
@@ -774,7 +817,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 != ""){
@@ -784,16 +826,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
             }
@@ -864,7 +912,6 @@
                     }
                     statusList[tempIndex] = Number(statusList[tempIndex]) + 1
                 }
-
                 if (statusList[1] > 0) {
                     tempObj.obj.status = 1
                 }
@@ -872,7 +919,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
@@ -904,7 +954,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")
@@ -912,6 +962,9 @@
                         }
                     }
                 }
+                if (s == '2' && !one && !two && witch.content.length == 0) {
+                  return
+                }
                 witch.status = s;
                 if (two) {
                     this.checkOneStatus({
@@ -923,11 +976,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,
@@ -937,8 +993,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) {
@@ -1016,7 +1071,7 @@
                         }
                         break
                     }
-                    case "多包信息": {pfInput
+                    case "多包信息": {
                         tempNode = {
                             //content: [],
                             show:true,
@@ -1051,7 +1106,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)
                 })
             },
@@ -1067,7 +1122,7 @@
                 input:"",
                 key: 'bidamount',
                 status:"2",
-                title: '标段(包)中金额'
+                title: '标段(包)中金额'
               })
               two.status = 2
               this.checkOneStatus({
@@ -1089,7 +1144,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")
@@ -1103,6 +1158,8 @@
                         v.status = n
                     } else if (n=="2"){
                         v.status = n
+                    }else if (n=="4"){
+                        v.status = n
                     }
                 });
                 two.status = n
@@ -1137,7 +1194,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")
@@ -1160,18 +1217,6 @@
                         type: false
                     })
                 });
-                // one.content.forEach(function(v) {
-                //     if (v.content) {
-                //         v.content.forEach(function(i) {
-                //             i.uInput.forEach(function(value) {
-                //                 if (value.input && value.input != '') {
-                //                     value.status = n
-                //                 }
-                //             })
-                //         })
-                //     }
-                // });
-                //保存当前标记
             },
             //验证保存提示
             open:function(stype) {
@@ -1186,9 +1231,32 @@
             },
             //保存事件
             upChange: function (stype) {
+                console.log(this.editData)
+                var noTagKey = [];
+                this.editData.filter(function (one) {
+                  console.log("title---",one.title,one.status)
+                  if(one.title == "标的信息"||one.title == "多包信息"||one.title == "中标候选人信息"){
+                    if(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) {
+                if (stype == 1) {//全部字段验证
                     var checkAllKey = this.editData.filter(function (one) {
                         var otherOne = one.content.filter(function(v) {
                             return v.uInput.filter(function (u) {
@@ -1202,40 +1270,82 @@
                         }
                     })
                     resultStatus = !Boolean(checkAllKey.length)
-                } else {
-                    var checkOnlyKey = this.editData.filter(function (one) {
-                        if (one.title=="标的信息"||one.title=="多包信息"||one.title=="中标候选人信息") {
-                            if (one.status == "-1") {
-                                return false
+                } 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) {
-                                    return true
+                                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
+                                    }
+                                  }
                                 }
-                                var otherOne = one.content.filter(function(v) {
-                                    return v.uInput.filter(function (u) {
-                                        return u.status == '-1'
-                                    }).length
-                                })
-                                return !(otherOne.length > 0)
                             }
-                        } else {
-                            var otherOne = one.content.filter(function(v) {
+                          } else {
+                            var baseOne = one.content.filter(function(v) {
                                 return v.uInput.filter(function (u) {
                                     return u.status != '-1'
                                 }).length
                             })
-                            return otherOne.length
+                            if (baseOne.length >0){//基本字段
+                              baseTag = 1
+                            }
+                          }
                         }
                     })
-                    resultStatus = Boolean(checkOnlyKey.length)
+                    if(otherTag == 0 && baseTag == 1){
+                      resultStatus = true
+                    }else if (otherTag == 1){
+                      resultStatus = true
+                    }
                 }
-
                 if (!resultStatus) {
                     this.$alert("未标注完成");
                     return
                 }
                 var d= JSON.stringify(this.editData);
-                //console.log(d)
+                console.log(d)
                 var _this = this
                 $.ajax({
                     url:"/center/biaozhu",
@@ -1249,13 +1359,7 @@
                             duration: 1000,
                             offset: 300
                           });
-                          //  document.getElementById("com-alert-val").innerHtml="保存成功";
-                          //  var label1 = document.getElementById("com-alert");
-                          //  label1.style.display="block";
-                          //  setTimeout(function(){
-                          //      label1.style.display="none";
-                          //  },1000)
-                            issave = true//保存成功
+                          issave = true//保存成功
                         }
                     },
                     error:function(err){
@@ -1281,7 +1385,6 @@
             },
             //一级保存
             saveOneData: function (one) {
-                console.log(one.status)
                 if (one.title=="标的信息"||one.title=="多包信息"||one.title=="中标候选人信息"){
                     if(one.status ==  "-1"){
                         this.$alert(one.title+" 未标注完成")
@@ -1299,7 +1402,6 @@
                     }
                 }
                 onetext = "["+ JSON.stringify(one) +"]";
-                console.log(onetext)
                 $.ajax({
                     url:"/center/biaozhu",
                     method:"post",