Jianghan 3 anni fa
parent
commit
806fa09937

+ 36 - 2
src/config.json

@@ -7,7 +7,7 @@
     "defaultpwd": "123",
     "bidding":{
         "addr":"192.168.3.207:27092",
-        "db": "mxs",
+        "db": "wjh",
         "coll1": "bidding",
         "coll2": "bidding_back",
         "size": 10,
@@ -30,7 +30,7 @@
         "size": 10
     },
     "es":{
-        "addr": "http://192.168.3.206:9800",
+        "addr": "http://127.0.0.1:9800",
         "index": "bidding",
         "itype": "bidding",
         "pool": 12
@@ -78,6 +78,14 @@
         "结果": ["废标","流标","结果变更","中标","成交","其它"],
         "其它": ["合同","验收","违规","其它"]
     },
+    "dataType": {
+        "招标公告": ["projectcode", "area", "city", "budget", "buyer"],
+        "中标公告": ["projectcode", "area", "city", "budget", "bidamount", "buyer", "s_winner"],
+        "标的物公告": ["projectcode", "area", "city", "budget", "bidamount", "buyer", "s_winner", "purchasinglist.itemname",
+            "purchasinglist.brandname", "purchasinglist.modal", "purchasinglist.unitprice", "purchasinglist.number"],
+        "采购意向公告": ["area", "city", "buyer", "purchasinglist.projectname", "purchasinglist.buyer", "purchasinglist.totalprice",
+            "purchasinglist.projectscope", "purchasinglist.expurasingtime"]
+    },
     "biaozhu": {
         "common": [
             {
@@ -205,6 +213,32 @@
                 "descript": "尺寸"
             }
         ],
+        "purchasinglist_1": [
+            {
+                "key": "projectname",
+                "descript": "采购项目名称"
+            },
+            {
+                "key": "buyer",
+                "descript": "采购单位"
+            },
+            {
+                "key": "item",
+                "descript": "采购品目"
+            },
+            {
+                "key": "projectscope",
+                "descript": "采购需求/内容"
+            },
+            {
+                "key": "totalprice",
+                "descript": "采购预算"
+            },
+            {
+                "key": "expurasingtime",
+                "descript": "预计采购时间"
+            }
+        ],
         "package": [
             {
                 "key": "serial_number",

+ 12 - 9
src/front/front.go

@@ -59,8 +59,9 @@ type Front struct {
 	roleSecondEdit xweb.Mapper `xweb:"/front/role/second/edit"` //二级权限编辑
 
 	//project
-	projectList              xweb.Mapper `xweb:"/front/project"`                   //项目列表
-	projectSave              xweb.Mapper `xweb:"/front/project/save"`              //新增项目
+	projectList              xweb.Mapper `xweb:"/front/project"`      //项目列表
+	projectSave              xweb.Mapper `xweb:"/front/project/save"` //新增项目
+	projectAddData           xweb.Mapper `xweb:"/front/project/new/data"`
 	projectComplete          xweb.Mapper `xweb:"/front/project/complete"`          //项目完成
 	projectQualityAssessment xweb.Mapper `xweb:"/front/project/qualityAssessment"` //数据质量评估
 	projectGroupTaskSave     xweb.Mapper `xweb:"/front/project/task/save"`         //用户组任务分发
@@ -97,13 +98,15 @@ type Front struct {
 	remarkDetail   xweb.Mapper `xweb:"/front/user/remark/detail"`
 
 	//check
-	checkList       xweb.Mapper `xweb:"/front/user/check/list"`
-	checkData       xweb.Mapper `xweb:"/front/user/check/data"`
-	checkDetail     xweb.Mapper `xweb:"/front/user/check/detail"`
-	checkSave       xweb.Mapper `xweb:"/front/user/check/save"`
-	checkResult     xweb.Mapper `xweb:"/front/user/check/result"`
-	checkExcpResult xweb.Mapper `xweb:"/front/check/excp/result"`     // 异常数据
-	checkExcpData   xweb.Mapper `xweb:"/front/check/excp/notag/data"` //达标数据
+	checkList         xweb.Mapper `xweb:"/front/user/check/list"`
+	checkData         xweb.Mapper `xweb:"/front/user/check/data"`
+	checkJyData       xweb.Mapper `xweb:"/front/jy/check/data"` // jy质检
+	checkDetail       xweb.Mapper `xweb:"/front/user/check/detail"`
+	checkSave         xweb.Mapper `xweb:"/front/user/check/save"`
+	checkResult       xweb.Mapper `xweb:"/front/user/check/result"`
+	checkExcpResult   xweb.Mapper `xweb:"/front/check/excp/result"`     // 异常数据
+	checkExcpData     xweb.Mapper `xweb:"/front/check/excp/notag/data"` //达标数据
+	checkDataPurchase xweb.Mapper `xweb:"/front/check/data/purchase"`   // 标的物有效性检查
 }
 
 func (f *Front) Index() {

+ 0 - 826
src/front/mark.go

@@ -1,826 +0,0 @@
-package front
-
-import (
-	"encoding/json"
-	"fmt"
-	"mongodb"
-	qu "qfw/util"
-	"strings"
-	"time"
-	"util"
-)
-
-// JyMarkList 剑鱼管理员标注信息列表
-func (f *Front) JyMarkList() {
-	defer qu.Catch()
-	stype := f.GetString("stype") //all:全量标注;notag:达标数据标注;tag:未达标数据标注
-	if f.Method() == "POST" {
-		start, _ := f.GetInteger("start")
-		limit, _ := f.GetInteger("length")
-		draw, _ := f.GetInteger("draw")
-		sourceInfo := f.GetString("s_sourceinfo") //数据源表
-		istag := f.GetString("b_istag")           //
-		field := f.GetString("field")             //字段
-		dataType := f.GetString("datatype")       //信息类型
-		min := f.GetString("minval")              //min max不用int类型接收,以免有默认值0
-		max := f.GetString("maxval")
-		hasno, _ := f.GetBool("hasno")   //是否存在
-		notag, _ := f.GetBool("notag")   //是否标注
-		query := map[string]interface{}{ //剑鱼自用的标注页面, 查询待分发的数据量
-			"b_isgivegroup": false,
-			//"b_isgiveuser":  false,
-		}
-		if istag == "true" {
-			query["b_istag"] = true
-		} else if istag == "false" {
-			query["b_istag"] = false
-		}
-		if stype == "notag" { //查询达标
-			query["b_istagging"] = false
-		} else if stype == "tag" { //查询未达标
-			query["b_istagging"] = true
-		}
-		if dataType != "-1" && dataType != "" { //类型
-			if dataType == util.SPECIALTYPE {
-				query["v_baseinfo.subtype"] = map[string]interface{}{
-					"$exists": false,
-				}
-			} else {
-				subtype := strings.Split(dataType, "-")[1]
-				query["v_baseinfo.subtype"] = subtype
-			}
-		}
-		fieldScreen := false
-		if field != "-1" && field != "" { //字段
-			fieldScreen = true
-			queryfield := map[string]interface{}{
-				"$exists": !hasno,
-			}
-			numMap := map[string]interface{}{}
-			if field == "budget" || field == "bidamount" { //金额区间
-				if min != "" {
-					minint := qu.IntAll(min)
-					numMap["$gte"] = minint
-				}
-				if max != "" {
-					maxint := qu.IntAll(max)
-					numMap["$lte"] = maxint
-				}
-			}
-			if len(numMap) > 0 {
-				if !hasno {
-					query["v_baseinfo."+field] = numMap
-				} else {
-					query["$or"] = []map[string]interface{}{
-						{"v_baseinfo." + field: queryfield},
-						{"v_baseinfo." + field: numMap},
-					}
-				}
-			} else {
-				if hasno {
-					query["$or"] = []interface{}{
-						map[string]interface{}{
-							"v_baseinfo." + field: queryfield,
-						},
-						map[string]interface{}{
-							"v_baseinfo." + field: map[string]interface{}{
-								"$eq": "",
-							},
-						},
-					}
-				} else {
-					query["$and"] = []interface{}{
-						map[string]interface{}{
-							"v_baseinfo." + field: queryfield,
-						},
-						map[string]interface{}{
-							"v_baseinfo." + field: map[string]interface{}{
-								"$ne": "",
-							},
-						},
-					}
-				}
-
-				//query["v_baseinfo."+field] = queryfield
-			}
-		}
-		if fieldScreen && notag {
-			query["v_taginfo."+field] = map[string]interface{}{
-				"$exists": false,
-			}
-		} else if !fieldScreen && notag {
-			query["i_ckdata"] = 0
-		}
-		count := util.Mgo.Count(sourceInfo, query)
-		qu.Debug("query:", query, sourceInfo, count)
-		fields := map[string]interface{}{"v_baseinfo.title": 1, "b_istag": 1, "i_ckdata": 1}
-		list, _ := util.Mgo.Find(sourceInfo, query, map[string]interface{}{"_id": 1}, fields, false, start, limit)
-		//checkedNum, allNum := GetCheckedAndAllDataInfo(query, coll) //已标和总数信息
-		f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
-	} else {
-		pid := f.GetString("pid")
-		info, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"s_sourceinfo": 1})
-		f.T["s_sourceinfo"] = (*info)["s_sourceinfo"]
-		f.T["stype"] = stype
-		f.T["pid"] = pid
-		f.T["topsubtype"] = util.TopSubStypeArr
-		f.T["allfield"] = util.AllFieldArr
-		_ = f.Render("project/remark_jy_list.html", &f.T)
-	}
-}
-
-// JyUserDataMark 剑鱼管理人员数据标注
-func (f *Front) JyUserDataMark() {
-	defer qu.Catch()
-	qu.Debug("jy save...")
-	success := false
-	msg := ""
-	user := f.GetSession("user").(map[string]interface{})
-	username := qu.ObjToString(user["s_login"]) //当前登录用户
-	groupId := qu.ObjToString(user["s_groupid"])
-	userId := qu.ObjToString(user["id"])       //当前登录用户标识
-	userRole := qu.ObjToString(user["i_role"]) //当前登录用户权限
-	obj := []map[string]interface{}{}
-	infoId := f.GetString("s_infoid")
-	sourceInfo := f.GetString("s_sourceinfo")
-	pid := f.GetString("pid")
-	qu.Debug("Data ID:", infoId)
-	data := f.GetString("data")
-	err := json.Unmarshal([]byte(data), &obj)
-	if err != nil {
-		qu.Debug("Json Unmarshal Error")
-		f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
-		return
-	}
-	tagSet := map[string]interface{}{}    //被标注字段状态
-	baseSet := map[string]interface{}{}   //要修改的字段信息
-	baseUnset := map[string]interface{}{} //要删除的字段信息
-	if len(obj) == 1 {                    //单独保存某个一级
-		content, ok := obj[0]["content"].([]interface{})
-		if !ok || len(content) == 0 {
-			f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
-			return
-		}
-		title := qu.ObjToString(obj[0]["title"])
-		istag, _ := obj[0]["checkAllTag"].(bool)
-		status := qu.IntAll(obj[0]["status"])
-		switch title {
-		case "基本字段":
-			MarkBase(content, tagSet, baseSet, baseUnset)
-		case "时间地点":
-			MarkTimePlace(content, tagSet, baseSet, baseUnset)
-		case "标的信息":
-			MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
-		case "多包信息":
-			MarkPackage(content, tagSet, baseSet, baseUnset, status)
-		case "中标候选人信息":
-			MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
-		case "其余信息":
-			MarkOther(content, tagSet, baseSet, baseUnset)
-		}
-	} else {
-		for j, val := range obj {
-			content, ok := val["content"].([]interface{})
-			status := qu.IntAll(val["status"])
-			if !ok {
-				qu.Debug("Content Error")
-				continue
-			}
-			istag, _ := val["checkAllTag"].(bool)
-			if j == 0 { //基本信息
-				MarkBase(content, tagSet, baseSet, baseUnset)
-			} else if j == 1 { //时间地点
-				MarkTimePlace(content, tagSet, baseSet, baseUnset)
-			} else if j == 2 { //标的物
-				MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
-			} else if j == 3 { //多包
-				MarkPackage(content, tagSet, baseSet, baseUnset, status)
-			} else if j == 4 { //候选人
-				MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
-			} else { //其余信息
-				MarkOther(content, tagSet, baseSet, baseUnset)
-			}
-		}
-	}
-	dataInfo, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1}) //查询标注保存前的原始信息
-	tagInfo, _ := (*dataInfo)["v_taginfo"].(map[string]interface{})
-	baseInfo, _ := (*dataInfo)["v_baseinfo"].(map[string]interface{})
-	if tagInfo != nil && len(tagInfo) > 0 {
-		for field, tmpStatus := range tagSet { //比对本次标注信息和历史标注信息
-			status := qu.IntAll(tmpStatus)            //此次被标注字段的状态
-			markedStatus := qu.IntAll(tagInfo[field]) //历史标注状态
-			if status == 1 && markedStatus != 0 {     //此次标注结果为正确,且有历史标注记录,不做修改
-				qu.Debug("已标注字段field---", field)
-				delete(tagSet, field)
-				delete(baseSet, field)
-				//continue
-			}
-			//else {
-			//	qu.Debug("未标注字段field---", field, status)
-			//}
-		}
-	}
-	//
-	allTagFields := map[string]interface{}{} //记录此此标注所有标注信息,用于日志记录
-	for k, _ := range tagSet {
-		allTagFields[k] = true
-	}
-	for k, v := range baseSet {
-		allTagFields[k] = v
-	}
-	for k, _ := range baseUnset {
-		allTagFields[k] = nil
-	}
-	qu.Debug("allTagFields===", allTagFields)
-	qu.Debug("tagSet===", tagSet)
-
-	if len(tagSet) >= 0 || baseInfo["purchasinglist_alltag"] != nil { //purchasinglist_alltag特殊处理
-		//1、更新数据源信息
-		setResult := map[string]interface{}{ //更新字段集
-			"i_updatetime": time.Now().Unix(),
-			"i_ckdata":     2,
-			"b_istag":      true,
-			"s_userid":     userId,
-			"s_groupid":    groupId,
-			//"b_isgiveuser":  true,
-			//"b_isgivegroup": true,
-			"s_login": username,
-		}
-		for field, val := range tagSet { //更新标注字段
-			setResult["v_taginfo."+field] = val
-		}
-		for field, val := range baseSet { //更新基本字段
-			setResult["v_baseinfo."+field] = val
-		}
-		baseUnsetResult := map[string]interface{}{} //删除字段集
-		for field, _ := range baseUnset {           //删除基本字段
-			baseUnsetResult["v_baseinfo."+field] = ""
-		}
-		set := map[string]interface{}{
-			"$set": setResult,
-		}
-		if len(baseUnsetResult) > 0 {
-			set["$unset"] = baseUnsetResult
-		}
-		qu.Debug("set---", set)
-		success = util.Mgo.UpdateById(sourceInfo, infoId, set)
-		//2、更新marked表
-		tmp, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1, "i_ckdata": 1})
-		qu.Debug("infoId:", infoId)
-		delete((*tmp), "_id")
-		(*tmp)["updatetime"] = time.Now().Unix()
-		b := util.Mgo.Update(util.AllToColl, map[string]interface{}{"_id": mongodb.StringTOBsonId(infoId)}, map[string]interface{}{"$set": tmp}, true, false)
-		qu.Debug("Update Marked:", b)
-	}
-	/*
-		} else {
-			表示页面标注时未做修改标注
-		}
-	*/
-	//3、保存标注日志
-	project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"s_name": 1})
-	b := SaveLog(infoId, "", username, userId, userRole, qu.ObjToString((*project)["s_name"]), "标注", baseInfo, allTagFields)
-	qu.Debug("Save Log:", b)
-	f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
-}
-
-// UserDataMark 标注人员数据标注(基于任务的标注)
-func (f *Front) UserDataMark() {
-	defer qu.Catch()
-	success := false
-	msg := ""
-	user := f.GetSession("user").(map[string]interface{})
-	username := qu.ObjToString(user["s_login"]) //当前登录用户
-	userId := qu.ObjToString(user["id"])        //当前登录用户标识
-	userRole := qu.ObjToString(user["i_role"])  //当前登录用户权限
-
-	obj := []map[string]interface{}{}
-	infoId := f.GetString("s_infoid")
-	userTaskId := f.GetString("s_usertaskid")
-	qu.Debug("Task ID:", userTaskId, "	Data ID:", infoId)
-	data := f.GetString("data")
-	err := json.Unmarshal([]byte(data), &obj)
-	if err != nil {
-		qu.Debug("Json Unmarshal Error")
-		f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
-		return
-	}
-	tagSet := map[string]interface{}{}    //被标注字段状态
-	baseSet := map[string]interface{}{}   //要修改的字段信息
-	baseUnset := map[string]interface{}{} //要删除的字段信息
-	//isSaveMarked := false
-	if len(obj) == 1 { //单独保存某个一级
-		content, ok := obj[0]["content"].([]interface{})
-		if !ok || len(content) == 0 {
-			f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
-			return
-		}
-		title := qu.ObjToString(obj[0]["title"])
-		istag, _ := obj[0]["checkAllTag"].(bool)
-		status := qu.IntAll(obj[0]["status"])
-		switch title {
-		case "基本字段":
-			MarkBase(content, tagSet, baseSet, baseUnset)
-		case "时间地点":
-			MarkTimePlace(content, tagSet, baseSet, baseUnset)
-		case "标的信息":
-			MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
-		case "多包信息":
-			MarkPackage(content, tagSet, baseSet, baseUnset, status)
-		case "中标候选人信息":
-			MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
-		case "其余信息":
-			MarkOther(content, tagSet, baseSet, baseUnset)
-		}
-	} else {
-		for j, val := range obj {
-			content, ok := val["content"].([]interface{})
-			status := qu.IntAll(val["status"])
-			if !ok {
-				qu.Debug("Content Error")
-				continue
-			}
-			istag, _ := val["checkAllTag"].(bool)
-			if j == 0 { //基本信息
-				MarkBase(content, tagSet, baseSet, baseUnset)
-			} else if j == 1 { //时间地点
-				MarkTimePlace(content, tagSet, baseSet, baseUnset)
-			} else if j == 2 { //标的物
-				MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
-			} else if j == 3 { //多包
-				MarkPackage(content, tagSet, baseSet, baseUnset, status)
-			} else if j == 4 { //候选人
-				MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
-			} else { //其余信息
-				MarkOther(content, tagSet, baseSet, baseUnset)
-			}
-		}
-	}
-	//
-	userTask, _ := util.Mgo.FindById(util.TASKCOLLNAME, userTaskId, map[string]interface{}{"s_personid": 1, "s_personname": 1, "s_projectname": 1, "s_sourceinfo": 1})
-	if userTask == nil || len(*userTask) == 0 {
-		f.ServeJson(map[string]interface{}{"success": success, "msg": "查询用户任务失败"})
-		return
-	}
-	sourceInfo := qu.ObjToString((*userTask)["s_sourceinfo"])                                                     //数据源表
-	dataInfo, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1}) //查询标注保存前的原始信息
-	tagInfo, _ := (*dataInfo)["v_taginfo"].(map[string]interface{})
-	baseInfo, _ := (*dataInfo)["v_baseinfo"].(map[string]interface{})
-	if tagInfo != nil && len(tagInfo) > 0 {
-		for field, tmpStatus := range tagSet { //比对本次标注信息和历史标注信息
-			status := qu.IntAll(tmpStatus)            //此次被标注字段的状态
-			markedStatus := qu.IntAll(tagInfo[field]) //历史标注状态
-			if status == 1 && markedStatus != 0 {     //此次标注结果为正确,且有历史标注记录,不做修改
-				qu.Debug("已标注字段field---", field)
-				delete(tagSet, field)
-				delete(baseSet, field)
-				//continue
-			}
-			//else {
-			//	qu.Debug("未标注字段field---", field, status)
-			//}
-		}
-	}
-	//
-	allTagFields := map[string]interface{}{} //记录此此标注所有标注信息,用于日志记录
-	for k, _ := range tagSet {
-		allTagFields[k] = true
-	}
-	for k, v := range baseSet {
-		allTagFields[k] = v
-	}
-	for k, _ := range baseUnset {
-		allTagFields[k] = nil
-	}
-	qu.Debug("allTagFields===", allTagFields)
-	qu.Debug("tagSet===", tagSet)
-	if len(tagSet) >= 0 || baseInfo["purchasinglist_alltag"] != nil { //purchasinglist_alltag特殊处理
-		//1、更新数据源信息
-		setResult := map[string]interface{}{ //更新字段集
-			"i_updatetime": time.Now().Unix(),
-			"i_ckdata":     2,
-			"b_istag":      true,
-		}
-		for field, val := range tagSet { //更新标注字段
-			setResult["v_taginfo."+field] = val
-		}
-		for field, val := range baseSet { //更新基本字段
-			setResult["v_baseinfo."+field] = val
-			baseInfo[field] = val
-		}
-		baseUnsetResult := map[string]interface{}{} //删除字段集
-		for field, _ := range baseUnset {           //删除基本字段
-			baseUnsetResult["v_baseinfo."+field] = ""
-			delete(baseInfo, field)
-		}
-		ex, exp := DataException(baseInfo)
-		if ex != "" {
-			setResult["s_excp"] = ex
-			setResult["s_excp_info"] = exp
-		}
-		set := map[string]interface{}{
-			"$set": setResult,
-		}
-		if len(baseUnsetResult) > 0 {
-			set["$unset"] = baseUnsetResult
-		}
-		qu.Debug("set---", set)
-		success = util.Mgo.UpdateById(sourceInfo, infoId, set)
-		//2、更新marked表
-		tmp, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1, "i_ckdata": 1})
-		qu.Debug("infoId:", infoId)
-		delete((*tmp), "_id")
-		(*tmp)["updatetime"] = time.Now().Unix()
-		b := util.Mgo.Update(util.AllToColl, map[string]interface{}{"_id": mongodb.StringTOBsonId(infoId)}, map[string]interface{}{"$set": tmp}, true, false)
-		qu.Debug("Update Marked:", b)
-	}
-	/*
-		} else {
-			表示页面标注时未做修改标注
-		}
-	*/
-	//3、修改任务状态
-	b := util.Mgo.Update(util.TASKCOLLNAME, map[string]interface{}{"_id": (*userTask)["_id"], "s_status": "未开始"}, map[string]interface{}{
-		"$set": map[string]interface{}{
-			"i_starttime":    time.Now().Unix(),
-			"i_updatetime":   time.Now().Unix(),
-			"s_updateperson": username,
-			"s_status":       "进行中",
-		},
-	}, false, false)
-	qu.Debug("Update UserTask:", b)
-	//4、保存标注日志
-	b = SaveLog(infoId, userTaskId, username, userId, userRole, qu.ObjToString((*userTask)["s_projectname"]), "标注", baseInfo, allTagFields)
-	qu.Debug("Save Log:", b)
-	f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
-}
-
-// MarkBase 标注基本信息
-func MarkBase(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}) {
-	defer qu.Catch()
-	info, _ := content[0].(map[string]interface{})
-	if uInputs, ok := info["uInput"].([]interface{}); ok {
-		for _, tmp := range uInputs {
-			if tmpMap, ok := tmp.(map[string]interface{}); ok {
-				if status := qu.IntAll(tmpMap["status"]); status != -1 {
-					key := qu.ObjToString(tmpMap["key"]) //字段
-					if key == "" {
-						continue
-					}
-					if status == 2 { //新增、修改、删除
-						input := tmpMap["input"]                                                                                               //值
-						if key == "bidamounttype" || key == "subtype" || key == "attach_discern" || key == "attach_ext" || key == "isrepeat" { //附件识别、抽取select
-							input = tmpMap["select"]
-						}
-						if input == "" { //删除原字段
-							baseUnset[key] = ""
-						} else { //修改原字段
-							if key == "budget" || key == "bidamount" || key == "biddiscount" {
-								input = qu.Float64All(input)
-								//input, _ = strconv.ParseFloat(qu.ObjToString(input), 32)
-							}
-							if key == "subtype" {
-								if topsubtype := strings.Split(qu.ObjToString(input), "-"); len(topsubtype) == 2 {
-									baseSet["toptype"] = topsubtype[0]
-									baseSet[key] = topsubtype[1]
-								}
-							} else if key == "s_winner" {
-								if strings.Contains(qu.ObjToString(input), ",") {
-									baseSet[key] = strings.ReplaceAll(qu.ObjToString(input), ",", ",")
-								} else {
-									baseSet[key] = input
-								}
-							} else {
-								baseSet[key] = input
-							}
-						}
-					}
-					tagSet[key] = status //记录被标注状态
-				}
-			}
-		}
-	}
-	qu.Debug("tagSet===", tagSet)
-	qu.Debug("baseSet===", baseSet)
-	qu.Debug("baseUnset===", baseUnset)
-}
-
-// MarkTimePlace 标注时间地点
-func MarkTimePlace(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}) {
-	info, _ := content[0].(map[string]interface{})
-	if uInputs, ok := info["uInput"].([]interface{}); ok {
-		for _, tmp := range uInputs {
-			if tmpMap, ok := tmp.(map[string]interface{}); ok {
-				if status := qu.IntAll(tmpMap["status"]); status != -1 {
-					key := qu.ObjToString(tmpMap["key"]) //字段
-					if key == "" {
-						continue
-					}
-					if status == 2 { //新增、修改、删除
-						input := tmpMap["input"] //值
-						if input == "" {
-							baseUnset[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)
-							}
-							baseSet[key] = input
-						}
-					}
-					tagSet[key] = status
-				}
-			}
-		}
-	}
-	qu.Debug("tagSet===", tagSet)
-	qu.Debug("baseSet===", baseSet)
-	qu.Debug("baseUnset===", baseUnset)
-}
-
-// MarkPurchasinglist 标注标的信息
-func MarkPurchasinglist(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}, istag bool, status int) {
-	if status == -1 {
-		return
-	}
-	baseSet["purchasinglist_alltag"] = istag //标的信息是否标注完全
-	purchasinglist := []interface{}{}
-	delpclson := 0
-	for _, con := range content {
-		info, _ := con.(map[string]interface{})
-		isNew, _ := info["isnew"].(bool) //是否是新增子包
-		pclSonStatus := qu.IntAll(info["status"])
-		if pclSonStatus == 4 {
-			delpclson++
-		}
-		if uInputs, ok := info["uInput"].([]interface{}); ok {
-			result := map[string]interface{}{
-				"isnew": isNew,
-			}
-			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 input == "" { //判断前台页面是否填值,无值不进行字段存储
-						isNull = true
-					} else if key == "number" || key == "unitprice" || key == "totalprice" {
-						input = qu.Float64All(input)
-					}
-					if !isNull { //避免数字类型的字段在没有填写值的情况默认给0
-						result[key] = input
-					}
-				}
-			}
-			if pclSonStatus != -1 { //没有标注的标的信息不打标记
-				result["purchasinglist_son"] = pclSonStatus
-			}
-			if len(result) > 0 && pclSonStatus != 4 {
-				purchasinglist = append(purchasinglist, result)
-			}
-		}
-	}
-	qu.Debug("purchasinglist", len(purchasinglist))
-	if len(purchasinglist)+delpclson == len(content) {
-		if len(purchasinglist) > 0 {
-			baseSet["purchasinglist"] = purchasinglist
-		} else if len(content) > 0 && delpclson == len(content) { //只有删除
-			baseUnset["purchasinglist"] = ""
-		}
-		tagSet["purchasinglist"] = status
-	} else {
-		qu.Debug("Purchasinglist Tag Error")
-	}
-	qu.Debug("tagSet===", tagSet)
-	qu.Debug("baseSet===", baseSet)
-	qu.Debug("baseUnset===", baseUnset)
-}
-
-// MarkPackage 标注多包信息
-func MarkPackage(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}, status int) {
-	if status == -1 {
-		return
-	}
-	pkgs := map[string]interface{}{}
-	newNum := 1
-	delpkgson := 0 //记录子包删除个数
-	for _, con := range content {
-		info, _ := con.(map[string]interface{})
-		pkgSonStatus := qu.IntAll(info["status"])
-		if pkgSonStatus == 4 {
-			delpkgson++
-		}
-		num := fmt.Sprint(info["num"])   //包号
-		isNew, _ := info["isnew"].(bool) //是否是新增子包
-		if isNew {                       //新增子包新建包名
-			num = "new" + fmt.Sprint(newNum)
-			newNum++
-		}
-		if uInputs, ok := info["uInput"].([]interface{}); ok {
-			result := map[string]interface{}{
-				"isnew": isNew,
-			}
-			winnerArr := []interface{}{}
-			bidamountArr := []interface{}{}
-			for _, tmp := range uInputs {
-				if tmpMap, ok := tmp.(map[string]interface{}); ok {
-					key := qu.ObjToString(tmpMap["key"]) //字段
-					input := tmpMap["input"]             //值
-					isNull := false                      //记录字段是否有值
-					if key == "bidamounttype" {
-						input = tmpMap["select"]
-					} else {
-						if input == "" { //判断前台页面是否填值,无值不进行字段存储
-							isNull = true
-						} else if key == "bidamount" || key == "budget" {
-							input = qu.Float64All(input)
-							//input, _ = strconv.ParseFloat(qu.ObjToString(input), 32)
-						}
-					}
-					if key == "winner" {
-						if isNull {
-							winnerArr = append(winnerArr, nil)
-						} else {
-							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
-					}
-				}
-			}
-			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(winner_all) > 0 {
-				result["winner_all"] = winner_all
-			}
-			result["package_son"] = pkgSonStatus
-
-			if len(result) > 0 && pkgSonStatus != 4 { //要删除的子包不再保存
-				pkgs[num] = result
-			}
-		}
-	}
-	qu.Debug("pkgs", len(pkgs))
-	if len(pkgs)+delpkgson == len(content) {
-		if len(pkgs) > 0 {
-			baseSet["package"] = pkgs
-		} else if len(content) > 0 && delpkgson == len(content) { //只有删除
-			baseUnset["package"] = ""
-		}
-		tagSet["package"] = status
-	} else {
-		qu.Debug("Package Tag Error")
-	}
-}
-
-//标注中标候选人信息
-func MarkWonderorder(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}, status int) {
-	if status == -1 {
-		return
-	}
-	winnerorder := []interface{}{}
-	delwodrson := 0
-	for _, con := range content {
-		info, _ := con.(map[string]interface{})
-		isNew, _ := info["isnew"].(bool) //是否是新增子包
-		wodrSonStatus := qu.IntAll(info["status"])
-		if wodrSonStatus == 4 {
-			delwodrson++
-		}
-		if uInputs, ok := info["uInput"].([]interface{}); ok {
-			result := map[string]interface{}{
-				"isnew": isNew,
-			}
-			for _, tmp := range uInputs {
-				if tmpMap, ok := tmp.(map[string]interface{}); ok {
-					key := qu.ObjToString(tmpMap["key"]) //字段
-					input := tmpMap["input"]             //值
-					isNull := false
-					if input == "" { //判断前台页面是否填值,无值不进行字段存储
-						isNull = true
-					} else if key == "price" {
-						input = qu.Float64All(input)
-						//input, _ = strconv.ParseFloat(qu.ObjToString(input), 32)
-					}
-					if !isNull { //避免数字类型的字段在没有填写值的情况默认给0
-						result[key] = input
-					}
-					result["winnerorder_son"] = wodrSonStatus
-				}
-			}
-			if len(result) > 0 && wodrSonStatus != 4 {
-				winnerorder = append(winnerorder, result)
-			}
-		}
-	}
-	qu.Debug("winnerorder", len(winnerorder))
-	if len(winnerorder)+delwodrson == len(content) {
-		if len(winnerorder) > 0 {
-			baseSet["winnerorder"] = winnerorder
-		} else if len(content) > 0 && delwodrson == len(content) { //只有删除
-			baseUnset["winnerorder"] = ""
-		}
-		tagSet["winnerorder"] = status
-	} else {
-		qu.Debug("Winnerorder Tag Error")
-	}
-	qu.Debug("tagSet===", tagSet)
-	qu.Debug("baseSet===", baseSet)
-	qu.Debug("baseUnset===", baseUnset)
-}
-
-//标注其他信息
-func MarkOther(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}) {
-	info, _ := content[0].(map[string]interface{})
-	if uInputs, ok := info["uInput"].([]interface{}); ok {
-		for _, tmp := range uInputs {
-			if tmpMap, ok := tmp.(map[string]interface{}); ok {
-				if status := qu.IntAll(tmpMap["status"]); status != -1 {
-					key := qu.ObjToString(tmpMap["key"]) //字段
-					if key == "" {
-						continue
-					}
-					if status == 2 { //新增、修改、删除
-						input := tmpMap["input"] //值
-						if key == "isppp" || key == "contract_guarantee" || key == "bid_guarantee" {
-							input = tmpMap["select"]
-						}
-						if input == "" {
-							baseUnset[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" ||
-								key == "biddiscount" {
-								input = qu.Float64All(input)
-								//input, _ = strconv.ParseFloat(qu.ObjToString(input), 32)
-							}
-							baseSet[key] = input
-						}
-					}
-					tagSet[key] = status
-				}
-			}
-		}
-	}
-	qu.Debug("tagSet===", tagSet)
-	qu.Debug("baseSet===", baseSet)
-	qu.Debug("baseUnset===", baseUnset)
-}
-
-// SaveLog 标注日志保存
-func SaveLog(s_infoid, s_usertaskid, username, userid, role, projectname, s_stype string, baseInfo, allTagFields map[string]interface{}) (success bool) {
-	defer qu.Debug()
-	v_before := map[string]interface{}{}
-	for f, v := range allTagFields {
-		if _, ok := v.(bool); ok && f != "purchasinglist_alltag" { //表示此次标注status=1的字段
-			allTagFields[f] = baseInfo[f]
-		}
-		v_before[f] = baseInfo[f]
-	}
-	save := map[string]interface{}{
-		"s_projectname": projectname,
-		"s_taskid":      s_usertaskid,
-		"s_infoid":      s_infoid,
-		"s_stype":       s_stype,
-		"s_userid":      userid,
-		"s_role":        role,
-		"s_username":    username,
-		"i_createtime":  time.Now().Unix(),
-		"v_before":      v_before,
-		"v_after":       allTagFields,
-	}
-	id := util.Mgo.Save(util.LOGCOLLNAME, save)
-	if id != "" {
-		success = true
-	}
-	return
-}

+ 136 - 24
src/front/project.go

@@ -60,8 +60,9 @@ func (f *Front) ProjectList() {
 	} else {
 		query := map[string]interface{}{"s_type": "tag"}
 		info, _ := util.Mgo.Find("v_field", query, nil, map[string]interface{}{"s_name": 1, "s_code": 1}, false, -1, -1)
-		qu.Debug(query, len(*info))
 		f.T["fields"] = *info
+		f.T["dataTypeArr"] = util.DataTypeArr
+		f.T["dataTypeMap"] = util.DataTypeMap
 		_ = f.Render("project/project_list.html", &f.T)
 	}
 }
@@ -107,7 +108,7 @@ func (f *Front) ProjectSave() {
 		qu.Debug(s_entname, s_departname, s_rulename)
 
 		if err == nil {
-			importDataNum = ImportDataByExcel(s_sourceinfo, mf, &success, &msg, &successNum)
+			importDataNum = ImportDataByExcel(s_sourceinfo, mf, &success, &msg, &successNum, true)
 		}
 		//保存项目信息
 		set = map[string]interface{}{
@@ -129,7 +130,7 @@ func (f *Front) ProjectSave() {
 			f.ServeJson(map[string]interface{}{"success": false, "msg": "数据导出ID字段"})
 			return
 		}
-		s_departname, s_entname, s_rulename, importDataNum = ImportDataByColl(s_sourceinfo, historyid, &success, &msg, &successNum)
+		s_departname, s_entname, s_rulename, importDataNum = ImportDataByColl(s_sourceinfo, historyid, &success, &msg, &successNum, true)
 		qu.Debug(s_departname, s_entname, s_rulename, importDataNum)
 		//保存项目信息
 		set = map[string]interface{}{
@@ -153,22 +154,35 @@ func (f *Front) ProjectSave() {
 		rulename := f.GetString("s_rulename")      //规则名称
 		s_rulename = strings.Split(rulename, ",")
 		s_personname := f.GetString("s_personname")
-		fields := f.GetString("v_fields")
+		s_datatype := f.GetString("s_datatype") //数据类型
+		fields := f.GetString("v_fields_diy")
+		fieldsAll := f.GetString("v_fields")
+		qu.Debug(fields)
+		qu.Debug(fieldsAll)
 		v_fields := map[string]interface{}{}
+		v_fieldsAll := map[string]interface{}{}
 		if err := json.Unmarshal([]byte(fields), &v_fields); err != nil {
 			qu.Debug("V_Filelds Unmarshal Failed:", err)
 			f.ServeJson(map[string]interface{}{"success": false, "msg": err})
 			return
 		}
+		if err := json.Unmarshal([]byte(fieldsAll), &v_fieldsAll); err != nil {
+			qu.Debug("v_FieldsAll Unmarshal Failed:", err)
+			f.ServeJson(map[string]interface{}{"success": false, "msg": err})
+			return
+		}
+
 		set = map[string]interface{}{
 			//"s_name":       s_name,                        //项目名称
 			//"s_entname":    s_entname,                     //公司名称
-			"s_departname": s_departname,                  //部门名称
-			"s_rulename":   strings.Join(s_rulename, ","), //规则名称
-			"v_fields":     v_fields,                      //标注字段
-			"i_updatetime": username,                      //更新人
-			"i_createtime": time.Now().Unix(),             //更新时间
-			"s_personname": s_personname,                  //售后人员
+			"s_departname":   s_departname,                  //部门名称
+			"s_rulename":     strings.Join(s_rulename, ","), //规则名称
+			"v_fields_diy":   v_fields,                      //标注字段
+			"v_fields":       v_fieldsAll,
+			"s_updateperson": username,          //更新人
+			"i_createtime":   time.Now().Unix(), //更新时间
+			"s_personname":   s_personname,      //售后人员
+			"s_datatype":     s_datatype,
 			//"i_starttime":,//开始时间
 			//"i_completetime",//结束时间
 		}
@@ -192,6 +206,94 @@ func (f *Front) ProjectSave() {
 	}
 }
 
+func (f *Front) ProjectAddData() {
+	defer qu.Catch()
+	if f.Method() == "POST" {
+		user := f.GetSession("user").(map[string]interface{})
+		username := qu.ObjToString(user["s_login"])
+		projectid := f.GetString("projectid")
+		stype := f.GetString("s_type")
+		info, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, projectid, nil)
+		if len(*info) > 0 {
+			success := false                         //导入数据是否成功
+			msg := ""                                //异常信息
+			importDataNum, successNum := 0, int64(0) //导入成功条数
+			s_sourceinfo := qu.ObjToString((*info)["s_sourceinfo"])
+			if stype == "excel" {
+				mf, _, err := f.GetFile("xlsx")
+				if err == nil {
+					importDataNum = ImportDataByExcel(s_sourceinfo, mf, &success, &msg, &successNum, false)
+					var addDataTag []map[string]interface{}
+					if (*info)["v_add_tag"] != nil {
+						arr := qu.ObjArrToMapArr((*info)["v_add_data"].([]interface{}))
+						addDataTag = append(addDataTag, arr...)
+					} else {
+						addDataTag = append(addDataTag, map[string]interface{}{
+							"s_importtype":   stype,
+							"i_importnum":    importDataNum,
+							"s_updateperson": username,
+							"i_updatetime":   time.Now().Unix(),
+						})
+					}
+					s_status := ""
+					if status := qu.ObjToString((*info)["s_status"]); status == "未开始" || status == "进行中" {
+						s_status = status
+					} else if status == "已完成" {
+						s_status = "进行中"
+					}
+					set := map[string]interface{}{
+						"i_importnum":  importDataNum + qu.IntAll((*info)["i_importnum"]), //导入数量
+						"s_status":     s_status,                                          //项目状态
+						"i_updatetime": time.Now().Unix(),
+						"v_add_data":   addDataTag,
+					}
+					util.Mgo.UpdateById(util.PROJECTCOLLNAME, projectid, map[string]interface{}{"$set": set})
+				}
+			} else if stype == "coll" {
+				historyid := f.GetString("s_historyid")
+				if historyid == "" {
+					f.ServeJson(map[string]interface{}{"success": false, "msg": "数据导出ID字段"})
+					return
+				}
+				_, _, _, importDataNum = ImportDataByColl(s_sourceinfo, historyid, &success, &msg, &successNum, false)
+				if !success {
+					f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
+					return
+				}
+				var addDataTag []map[string]interface{}
+				if (*info)["v_add_tag"] != nil {
+					arr := qu.ObjArrToMapArr((*info)["v_add_data"].([]interface{}))
+					addDataTag = append(addDataTag, arr...)
+				} else {
+					addDataTag = append(addDataTag, map[string]interface{}{
+						"s_importtype":   stype,
+						"i_importnum":    importDataNum,
+						"s_updateperson": username,
+						"i_updatetime":   time.Now().Unix(),
+					})
+				}
+				s_status := ""
+				if status := qu.ObjToString((*info)["s_status"]); status == "未开始" || status == "进行中" {
+					s_status = status
+				} else if status == "已完成" {
+					s_status = "进行中"
+				}
+				//保存项目信息
+				set := map[string]interface{}{
+					"i_importnum":  importDataNum + qu.IntAll((*info)["i_importnum"]), //导入数量
+					"s_status":     s_status,                                          //项目状态
+					"i_updatetime": time.Now().Unix(),
+					"v_add_data":   addDataTag,
+				}
+				util.Mgo.UpdateById(util.PROJECTCOLLNAME, projectid, map[string]interface{}{"$set": set})
+			}
+			f.ServeJson(map[string]interface{}{"success": success, "msg": msg, "importnum": importDataNum, "successnum": successNum, "failnum": int64(importDataNum) - successNum})
+		} else {
+			f.ServeJson(map[string]interface{}{"success": false, "msg": "项目查询失败"})
+		}
+	}
+}
+
 // ProjectComplete 项目提交完成
 func (f *Front) ProjectComplete() {
 	defer qu.Catch()
@@ -256,7 +358,7 @@ func (f *Front) ProjectQualityAssessment() {
 		if isAssessment, ok := (*project)["b_isassessment"].(bool); ok && !isAssessment {
 			if fields, ok := (*project)["v_fields"].(map[string]interface{}); ok && len(fields) > 0 {
 				var fieldsArr []string
-				for f, _ := range fields {
+				for f := range fields {
 					fieldsArr = append(fieldsArr, f)
 				}
 				sourceinfo := qu.ObjToString((*project)["s_sourceinfo"])
@@ -761,7 +863,7 @@ func DeleleDataTagInfo(sourceinfo string) {
 			}
 			unset := map[string]interface{}{}
 			if len(tagInfo) != 0 && len(checkInfo) != 0 { //有质检信息,删除v_taginfo未质检的字段
-				for f, _ := range tagInfo {
+				for f := range tagInfo {
 					if checkInfo[f] == nil {
 						delete(tagInfo, f)
 					}
@@ -877,7 +979,7 @@ func UpdateSourceInfoByGroup(sourceinfo, stype string, groupIdInfo map[string]ut
 }
 
 //ImportDataByExcel 通过excel获取数据源
-func ImportDataByExcel(s_sourceinfo string, mf multipart.File, success *bool, msg *string, successNum *int64) (importDataNum int) {
+func ImportDataByExcel(s_sourceinfo string, mf multipart.File, success *bool, msg *string, successNum *int64, createindex bool) (importDataNum int) {
 	defer qu.Catch()
 	binary, _ := ioutil.ReadAll(mf)
 	xls, _ := xlsx.OpenBinary(binary)
@@ -933,8 +1035,8 @@ func ImportDataByExcel(s_sourceinfo string, mf multipart.File, success *bool, ms
 	importDataNum = len(idInfoArr)
 	qu.Debug("Load Excel Count:", importDataNum)
 	if importDataNum > 0 {
-		GetDataById(idInfoArr, "excel", s_sourceinfo, success, msg, successNum)
-		if *success {
+		GetDataById(idInfoArr, "excel", s_sourceinfo, success, msg, successNum, !createindex)
+		if *success && createindex {
 			if !util.Mgo.CreateIndex(s_sourceinfo, util.SourceInfoIndexArr) { //创建数据源表同时生成字段索引
 				qu.Debug("创建数据源表:", s_sourceinfo, "失败")
 				return
@@ -949,7 +1051,7 @@ func ImportDataByExcel(s_sourceinfo string, mf multipart.File, success *bool, ms
 }
 
 //ImportDataByColl 通过表获取数据源
-func ImportDataByColl(s_sourceinfo, historyid string, success *bool, msg *string, successNum *int64) (departname, entname string, rulename []string, importDataNum int) {
+func ImportDataByColl(s_sourceinfo, historyid string, success *bool, msg *string, successNum *int64, createindex bool) (departname, entname string, rulename []string, importDataNum int) {
 	defer qu.Catch()
 	rulenameMap := map[string]bool{}
 	sess := util.MgoJy.GetMgoConn()
@@ -975,7 +1077,7 @@ func ImportDataByColl(s_sourceinfo, historyid string, success *bool, msg *string
 			appid := qu.ObjToString(tmp["appid"])          //根据appid查user表获取公司名称
 			departname = qu.ObjToString(tmp["departname"]) //部门名称。所有数据都应部门名称,若不一致,随机取
 			needField := map[string]interface{}{}
-			for f, _ := range util.CustomerFieldMap_EH {
+			for f := range util.CustomerFieldMap_EH {
 				if tmp[f] != nil {
 					needField[f] = tmp[f]
 				}
@@ -1003,13 +1105,13 @@ func ImportDataByColl(s_sourceinfo, historyid string, success *bool, msg *string
 		tmp = map[string]interface{}{}
 	}
 	wg.Wait()
-	for r, _ := range rulenameMap {
+	for r := range rulenameMap {
 		rulename = append(rulename, r)
 	}
 	importDataNum = len(idInfoArr) //查询数据总数
 	if importDataNum > 0 {
-		GetDataById(idInfoArr, "coll", s_sourceinfo, success, msg, successNum)
-		if *success {
+		GetDataById(idInfoArr, "coll", s_sourceinfo, success, msg, successNum, !createindex)
+		if *success && createindex {
 			if !util.Mgo.CreateIndex(s_sourceinfo, util.SourceInfoIndexArr) { //创建数据源表同时生成字段索引
 				qu.Debug("创建数据源表:", s_sourceinfo, "失败")
 				return
@@ -1023,7 +1125,7 @@ func ImportDataByColl(s_sourceinfo, historyid string, success *bool, msg *string
 }
 
 //GetDataById 通过id集从bidding、extract、project获取数据所有信息
-func GetDataById(idInfoArr []util.Data, importType, s_sourceinfo string, success *bool, msg *string, successNum *int64) {
+func GetDataById(idInfoArr []util.Data, importType, s_sourceinfo string, success *bool, msg *string, successNum *int64, newAdd bool) {
 	*success = true
 	var msgArr []string
 	wg := &sync.WaitGroup{}
@@ -1058,6 +1160,10 @@ func GetDataById(idInfoArr []util.Data, importType, s_sourceinfo string, success
 				tmpBidColl = util.BidColl2 //bidding_back
 			}
 			bidData, _ := util.MgoB.FindById(tmpBidColl, id, nil)
+			if qu.ObjToString((*bidData)["toptype"]) != "采购意向" {
+				// 导入数据时,删掉purchasinglist(排除采购意向数据)
+				delete(*bidData, "purchasinglist")
+			}
 			if bidData != nil && len(*bidData) > 0 { //bidding表数据存在
 				//2.查extract
 				extData, _ := util.MgoE.FindById(util.ExtColl1, id, map[string]interface{}{"attach_text": 0})
@@ -1134,8 +1240,8 @@ func GetDataById(idInfoArr []util.Data, importType, s_sourceinfo string, success
 				// 6.es查询项目合并信息
 				esQ := `{"query":{"bool":{"must":[{"term":{"ids":"` + id + `"}}]}}}`
 				info := util.Es.Get("projectset", "projectset", esQ)
-				projectId := qu.ObjToString((*info)[0]["_id"])
-				if projectId != "" && len(projectId) == 24 { //舍弃项目id为空和合并错误的
+				if len(*info) > 0 {
+					projectId := qu.ObjToString((*info)[0]["_id"])
 					project, _ := util.MgoE.FindById(util.ProjectColl, projectId, map[string]interface{}{"ids": 1})
 					if project != nil && len(*project) > 0 {
 						ids := qu.ObjArrToStringArr((*project)["ids"].([]interface{}))
@@ -1185,6 +1291,12 @@ func GetDataById(idInfoArr []util.Data, importType, s_sourceinfo string, success
 				//baseInfoMap["b_cleartag"] = false    //是否清理标注信息
 				baseInfoMap["b_isgiveuser"] = false //是否分配给用户
 				baseInfoMap["b_check"] = false      // 质检标记
+				baseInfoMap["b_isEff"] = false      // 标的物有效性
+				if newAdd {
+					// 新增数据带上数据达标标记
+					baseInfoMap["b_isprchasing"] = true
+					baseInfoMap["b_istagging"] = true
+				}
 				if util.Mgo.SaveByOriID(s_sourceinfo, baseInfoMap) {
 					atomic.AddInt64(successNum, 1) //保存成功计数
 				} else {
@@ -1225,7 +1337,7 @@ func UpdateMarkColl(bidData, markData, tagInfoMap, baseInfoMap *map[string]inter
 	ckdata := qu.IntAll((*markData)["i_ckdata"])
 	v_taginfo := (*markData)["v_taginfo"].(map[string]interface{})   //标注信息
 	v_baseinfo := (*markData)["v_baseinfo"].(map[string]interface{}) //基本信息
-	for fk, _ := range v_taginfo {
+	for fk := range v_taginfo {
 		if v_baseinfo[fk] != nil {
 			(*bidData)[fk] = v_baseinfo[fk] //字段更新
 		}

+ 1084 - 14
src/front/remark.go

@@ -95,6 +95,7 @@ func (f *Front) RemarkDetail() {
 	f.T["purchasinglist"] = rep["purchasinglist"]
 	f.T["other"] = rep["other"]
 	f.T["PurchasinglistField"] = util.PurchasinglistField
+	f.T["PurchasinglistField1"] = util.PurchasinglistField1
 	f.T["WinnerorderField"] = util.WinnerorderField
 	f.T["PackageField"] = util.PackageField
 	f.T["topsubtype"] = util.TopSubStypeArr2
@@ -136,12 +137,12 @@ func getDetail(id, coll string) map[string]interface{} {
 	rep["packs"] = packs
 	rep["packskey"] = packskey
 	rep["pkg_new"] = pkg_new
-	if qu.IntAll((*infoTmp)["i_ckdata"]) == 2 {
-		// 首次标注数据不显示标的物信息
-		purchasinglist, isNewStatus := setPurchasingMap(baseInfo) //标的物
-		rep["purchasinglist"] = purchasinglist
-		rep["pcl_new"] = isNewStatus
-	}
+	purchasinglist, isNewStatus := setPurchasingMap(baseInfo) //标的物
+	rep["purchasinglist"] = purchasinglist
+	rep["pcl_new"] = isNewStatus
+	purchasinglist_1, isNewStatus1 := setPurchasingMap1(baseInfo) //标的物(采购意向)
+	rep["purchasinglist_1"] = purchasinglist_1
+	rep["pcl_new_1"] = isNewStatus1
 	worder, worder_new := setWorderMap(baseInfo) //中标候选人
 	rep["worder"] = worder
 	rep["worder_new"] = worder_new
@@ -391,6 +392,49 @@ func setPurchasingMap(info map[string]interface{}) ([]interface{}, []map[string]
 	return purchasinglists, isNewAndStatus
 }
 
+func setPurchasingMap1(info map[string]interface{}) ([]interface{}, []map[string]interface{}) {
+	purchasinglist, _ := util.BiaoZhu["purchasinglist_1"].([]interface{})
+	var purchasinglists []interface{}
+	//isNewPcl := []bool{} //记录子包是否是新增的
+	var 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["isnew"].(bool)
+				isNew := false
+				status := "-1"
+				if pcl["purchasinglist_son"] != nil {
+					status = "1"
+				}
+				//isNewPcl = append(isNewPcl, isNew)
+				isNewAndStatus = append(isNewAndStatus, map[string]interface{}{"isnew": isNew, "status": status})
+				var pcls []interface{}
+				for _, ps := range purchasinglist {
+					ps, _ := ps.(map[string]interface{})
+					value := pcl[qu.ObjToString(ps["key"])]
+					if value == nil {
+						value = ""
+					}
+					tp := map[string]interface{}{
+						"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"
+					// }
+					pcls = append(pcls, tp)
+				}
+				purchasinglists = append(purchasinglists, pcls)
+			}
+		}
+	}
+	return purchasinglists, isNewAndStatus
+}
+
 //拼装中标候选人
 func setWorderMap(info map[string]interface{}) ([]interface{}, []map[string]interface{}) {
 	//基本参数--中标候选人
@@ -645,6 +689,60 @@ func (f *Front) CheckList() {
 }
 
 func (f *Front) CheckData() {
+	qu.Catch()
+	pid := f.GetString("pid")
+	gid := f.GetString("gid")
+	tid := f.GetString("tid")
+	sourceinfo := f.GetString("s_sourceinfo")
+	if f.Method() == "POST" {
+		start, _ := f.GetInteger("start")
+		limit, _ := f.GetInteger("length")
+		draw, _ := f.GetInteger("draw")
+		query := make(map[string]interface{})
+		query["b_istag"] = true
+		query["s_usertaskid"] = tid
+		status := f.GetString("s_status")
+		s_excp := f.GetString("s_excp")
+
+		if status == "1" {
+			query["b_check"] = true
+		} else if status == "-1" {
+			query["b_check"] = false
+		}
+		if s_excp == "1" {
+			query["s_excp"] = nil
+		} else if s_excp == "-1" {
+			query["s_excp"] = map[string]interface{}{"$exists": true}
+		}
+		qu.Debug(query)
+		count := util.Mgo.Count(sourceinfo, query)
+		fields := map[string]interface{}{"v_baseinfo.title": 1, "b_check": 1, "i_ckdata": 1, "s_login": 1, "b_istag": 1, "s_excp": 1, "s_excp_info": 1}
+		info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, fields, false, start, limit)
+		f.ServeJson(map[string]interface{}{
+			"draw":            draw,
+			"data":            *info,
+			"recordsFiltered": count,
+			"recordsTotal":    count,
+		})
+	} else {
+		task, _ := util.Mgo.FindById(util.TASKCOLLNAME, tid, map[string]interface{}{"i_givenum": 1})
+		f.T["taskNum"] = (*task)["i_givenum"]
+		tagCount, checkCount := 0, 0
+		tagCount = util.Mgo.Count(sourceinfo, map[string]interface{}{"s_usertaskid": tid, "b_istag": true})
+		checkCount = util.Mgo.Count(sourceinfo, map[string]interface{}{"s_usertaskid": tid, "b_check": true})
+		f.T["taskTagNum"] = tagCount
+		f.T["taskCheckNum"] = checkCount
+		f.T["pid"] = pid
+		f.T["tid"] = tid
+		f.T["gid"] = gid
+		f.T["sourceinfo"] = sourceinfo
+		f.T["topsubtype"] = util.TopSubStypeArr
+		f.T["allfield"] = util.AllFieldArr
+		_ = f.Render("project/check_user_data_list.html", &f.T)
+	}
+}
+
+func (f *Front) CheckJyData() {
 	qu.Catch()
 	pid := f.GetString("pid")
 	gid := f.GetString("gid")
@@ -656,8 +754,6 @@ func (f *Front) CheckData() {
 		start, _ := f.GetInteger("start")
 		limit, _ := f.GetInteger("length")
 		draw, _ := f.GetInteger("draw")
-		searchStr := f.GetString("search[value]")
-		search := strings.TrimSpace(searchStr)
 		query := make(map[string]interface{})
 		if tid != "" {
 			// 任务数据质检
@@ -689,6 +785,12 @@ func (f *Front) CheckData() {
 		}
 		status := f.GetString("s_status")
 		s_excp := f.GetString("s_excp")
+		field := f.GetString("field")         //字段
+		dataType1 := f.GetString("datatype1") //信息类型
+		min := f.GetString("minval")          //min max不用int类型接收,以免有默认值0
+		max := f.GetString("maxval")
+		hasno, _ := f.GetBool("hasno") //是否存在
+		notag, _ := f.GetBool("notag") //是否标注
 		if status == "1" {
 			query["b_check"] = true
 		} else if status == "-1" {
@@ -699,16 +801,79 @@ func (f *Front) CheckData() {
 		} else if s_excp == "-1" {
 			query["s_excp"] = map[string]interface{}{"$exists": true}
 		}
-		if search != "" {
-			query["$or"] = []interface{}{
-				map[string]interface{}{"v_baseinfo.title": map[string]interface{}{"$regex": search}},
-				map[string]interface{}{"s_login": map[string]interface{}{"$regex": search}},
+		if dataType1 != "-1" && dataType1 != "" { //类型
+			if dataType1 == util.SPECIALTYPE {
+				query["v_baseinfo.subtype"] = map[string]interface{}{
+					"$exists": false,
+				}
+			} else {
+				subtype := strings.Split(dataType1, "-")[1]
+				query["v_baseinfo.subtype"] = subtype
+			}
+		}
+		fieldScreen := false
+		if field != "-1" && field != "" { //字段
+			fieldScreen = true
+			queryfield := map[string]interface{}{
+				"$exists": !hasno,
+			}
+			numMap := map[string]interface{}{}
+			if field == "budget" || field == "bidamount" { //金额区间
+				if min != "" {
+					minint := qu.IntAll(min)
+					numMap["$gte"] = minint
+				}
+				if max != "" {
+					maxint := qu.IntAll(max)
+					numMap["$lte"] = maxint
+				}
+			}
+			if len(numMap) > 0 {
+				if !hasno {
+					query["v_baseinfo."+field] = numMap
+				} else {
+					query["$or"] = []map[string]interface{}{
+						{"v_baseinfo." + field: queryfield},
+						{"v_baseinfo." + field: numMap},
+					}
+				}
+			} else {
+				if hasno {
+					query["$or"] = []interface{}{
+						map[string]interface{}{
+							"v_baseinfo." + field: queryfield,
+						},
+						map[string]interface{}{
+							"v_baseinfo." + field: map[string]interface{}{
+								"$eq": "",
+							},
+						},
+					}
+				} else {
+					query["$and"] = []interface{}{
+						map[string]interface{}{
+							"v_baseinfo." + field: queryfield,
+						},
+						map[string]interface{}{
+							"v_baseinfo." + field: map[string]interface{}{
+								"$ne": "",
+							},
+						},
+					}
+				}
 			}
 		}
+		if fieldScreen && notag {
+			query["v_taginfo."+field] = map[string]interface{}{
+				"$exists": false,
+			}
+		} else if !fieldScreen && notag {
+			query["i_ckdata"] = 0
+		}
+		qu.Debug(query)
+		count := util.Mgo.Count(sourceinfo, query)
 		fields := map[string]interface{}{"v_baseinfo.title": 1, "b_check": 1, "i_ckdata": 1, "s_login": 1, "b_istag": 1, "s_excp": 1, "s_excp_info": 1}
 		info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, fields, false, start, limit)
-		count := util.Mgo.Count(sourceinfo, query)
-		qu.Debug(query, sourceinfo, count)
 		f.ServeJson(map[string]interface{}{
 			"draw":            draw,
 			"data":            *info,
@@ -770,6 +935,8 @@ func (f *Front) CheckData() {
 		f.T["sourceinfo"] = sourceinfo
 		f.T["stype"] = stype
 		f.T["datatype"] = datatype
+		f.T["topsubtype"] = util.TopSubStypeArr
+		f.T["allfield"] = util.AllFieldArr
 		_ = f.Render("project/check_data_list.html", &f.T)
 	}
 }
@@ -808,6 +975,7 @@ func (f *Front) CheckDetail() {
 	f.T["purchasinglist"] = rep["purchasinglist"]
 	f.T["other"] = rep["other"]
 	f.T["PurchasinglistField"] = util.PurchasinglistField
+	f.T["PurchasinglistField1"] = util.PurchasinglistField1
 	f.T["WinnerorderField"] = util.WinnerorderField
 	f.T["PackageField"] = util.PackageField
 	f.T["topsubtype"] = util.TopSubStypeArr2
@@ -1271,3 +1439,905 @@ func DataException(tmp map[string]interface{}) (string, string) {
 	}
 	return strings.Join(tag, ","), exp
 }
+
+// JyMarkList 剑鱼管理员标注信息列表
+func (f *Front) JyMarkList() {
+	defer qu.Catch()
+	stype := f.GetString("stype") //all:全量标注;notag:达标数据标注;tag:未达标数据标注
+	if f.Method() == "POST" {
+		start, _ := f.GetInteger("start")
+		limit, _ := f.GetInteger("length")
+		draw, _ := f.GetInteger("draw")
+		sourceInfo := f.GetString("s_sourceinfo") //数据源表
+		istag := f.GetString("b_istag")           //
+		field := f.GetString("field")             //字段
+		dataType := f.GetString("datatype")       //信息类型
+		min := f.GetString("minval")              //min max不用int类型接收,以免有默认值0
+		max := f.GetString("maxval")
+		hasno, _ := f.GetBool("hasno")   //是否存在
+		notag, _ := f.GetBool("notag")   //是否标注
+		query := map[string]interface{}{ //剑鱼自用的标注页面, 查询待分发的数据量
+			"b_isgivegroup": false,
+			//"b_isgiveuser":  false,
+		}
+		if istag == "true" {
+			query["b_istag"] = true
+		} else if istag == "false" {
+			query["b_istag"] = false
+		}
+		if stype == "notag" { //查询达标
+			query["b_istagging"] = false
+		} else if stype == "tag" { //查询未达标
+			query["b_istagging"] = true
+		}
+		if dataType != "-1" && dataType != "" { //类型
+			if dataType == util.SPECIALTYPE {
+				query["v_baseinfo.subtype"] = map[string]interface{}{
+					"$exists": false,
+				}
+			} else {
+				subtype := strings.Split(dataType, "-")[1]
+				query["v_baseinfo.subtype"] = subtype
+			}
+		}
+		fieldScreen := false
+		if field != "-1" && field != "" { //字段
+			fieldScreen = true
+			queryfield := map[string]interface{}{
+				"$exists": !hasno,
+			}
+			numMap := map[string]interface{}{}
+			if field == "budget" || field == "bidamount" { //金额区间
+				if min != "" {
+					minint := qu.IntAll(min)
+					numMap["$gte"] = minint
+				}
+				if max != "" {
+					maxint := qu.IntAll(max)
+					numMap["$lte"] = maxint
+				}
+			}
+			if len(numMap) > 0 {
+				if !hasno {
+					query["v_baseinfo."+field] = numMap
+				} else {
+					query["$or"] = []map[string]interface{}{
+						{"v_baseinfo." + field: queryfield},
+						{"v_baseinfo." + field: numMap},
+					}
+				}
+			} else {
+				if hasno {
+					query["$or"] = []interface{}{
+						map[string]interface{}{
+							"v_baseinfo." + field: queryfield,
+						},
+						map[string]interface{}{
+							"v_baseinfo." + field: map[string]interface{}{
+								"$eq": "",
+							},
+						},
+					}
+				} else {
+					query["$and"] = []interface{}{
+						map[string]interface{}{
+							"v_baseinfo." + field: queryfield,
+						},
+						map[string]interface{}{
+							"v_baseinfo." + field: map[string]interface{}{
+								"$ne": "",
+							},
+						},
+					}
+				}
+				//query["v_baseinfo."+field] = queryfield
+			}
+		}
+		if fieldScreen && notag {
+			query["v_taginfo."+field] = map[string]interface{}{
+				"$exists": false,
+			}
+		} else if !fieldScreen && notag {
+			query["i_ckdata"] = 0
+		}
+		count := util.Mgo.Count(sourceInfo, query)
+		qu.Debug("query:", query, sourceInfo, count)
+		fields := map[string]interface{}{"v_baseinfo.title": 1, "b_istag": 1, "i_ckdata": 1}
+		list, _ := util.Mgo.Find(sourceInfo, query, map[string]interface{}{"_id": 1}, fields, false, start, limit)
+		//checkedNum, allNum := GetCheckedAndAllDataInfo(query, coll) //已标和总数信息
+		f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
+	} else {
+		pid := f.GetString("pid")
+		info, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"s_sourceinfo": 1})
+		f.T["s_sourceinfo"] = (*info)["s_sourceinfo"]
+		f.T["stype"] = stype
+		f.T["pid"] = pid
+		f.T["topsubtype"] = util.TopSubStypeArr
+		f.T["allfield"] = util.AllFieldArr
+		_ = f.Render("project/remark_jy_list.html", &f.T)
+	}
+}
+
+// JyUserDataMark 剑鱼管理人员数据标注
+func (f *Front) JyUserDataMark() {
+	defer qu.Catch()
+	qu.Debug("jy save...")
+	success := false
+	msg := ""
+	user := f.GetSession("user").(map[string]interface{})
+	username := qu.ObjToString(user["s_login"]) //当前登录用户
+	groupId := qu.ObjToString(user["s_groupid"])
+	userId := qu.ObjToString(user["id"])       //当前登录用户标识
+	userRole := qu.ObjToString(user["i_role"]) //当前登录用户权限
+	obj := []map[string]interface{}{}
+	infoId := f.GetString("s_infoid")
+	sourceInfo := f.GetString("s_sourceinfo")
+	pid := f.GetString("pid")
+	qu.Debug("Data ID:", infoId)
+	data := f.GetString("data")
+	err := json.Unmarshal([]byte(data), &obj)
+	if err != nil {
+		qu.Debug("Json Unmarshal Error")
+		f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
+		return
+	}
+	tagSet := map[string]interface{}{}    //被标注字段状态
+	baseSet := map[string]interface{}{}   //要修改的字段信息
+	baseUnset := map[string]interface{}{} //要删除的字段信息
+	if len(obj) == 1 {                    //单独保存某个一级
+		content, ok := obj[0]["content"].([]interface{})
+		if !ok || len(content) == 0 {
+			f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
+			return
+		}
+		title := qu.ObjToString(obj[0]["title"])
+		istag, _ := obj[0]["checkAllTag"].(bool)
+		status := qu.IntAll(obj[0]["status"])
+		switch title {
+		case "基本字段":
+			MarkBase(content, tagSet, baseSet, baseUnset)
+		case "时间地点":
+			MarkTimePlace(content, tagSet, baseSet, baseUnset)
+		case "标的信息":
+			MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
+		case "多包信息":
+			MarkPackage(content, tagSet, baseSet, baseUnset, status)
+		case "中标候选人信息":
+			MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
+		case "其余信息":
+			MarkOther(content, tagSet, baseSet, baseUnset)
+		}
+	} else {
+		for j, val := range obj {
+			content, ok := val["content"].([]interface{})
+			status := qu.IntAll(val["status"])
+			if !ok {
+				qu.Debug("Content Error")
+				continue
+			}
+			istag, _ := val["checkAllTag"].(bool)
+			if j == 0 { //基本信息
+				MarkBase(content, tagSet, baseSet, baseUnset)
+			} else if j == 1 { //时间地点
+				MarkTimePlace(content, tagSet, baseSet, baseUnset)
+			} else if j == 2 { //标的物
+				MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
+			} else if j == 3 { //多包
+				MarkPackage(content, tagSet, baseSet, baseUnset, status)
+			} else if j == 4 { //候选人
+				MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
+			} else { //其余信息
+				MarkOther(content, tagSet, baseSet, baseUnset)
+			}
+		}
+	}
+	dataInfo, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1}) //查询标注保存前的原始信息
+	tagInfo, _ := (*dataInfo)["v_taginfo"].(map[string]interface{})
+	baseInfo, _ := (*dataInfo)["v_baseinfo"].(map[string]interface{})
+	if tagInfo != nil && len(tagInfo) > 0 {
+		for field, tmpStatus := range tagSet { //比对本次标注信息和历史标注信息
+			status := qu.IntAll(tmpStatus)            //此次被标注字段的状态
+			markedStatus := qu.IntAll(tagInfo[field]) //历史标注状态
+			if status == 1 && markedStatus != 0 {     //此次标注结果为正确,且有历史标注记录,不做修改
+				qu.Debug("已标注字段field---", field)
+				delete(tagSet, field)
+				delete(baseSet, field)
+				//continue
+			}
+			//else {
+			//	qu.Debug("未标注字段field---", field, status)
+			//}
+		}
+	}
+	//
+	allTagFields := map[string]interface{}{} //记录此此标注所有标注信息,用于日志记录
+	for k, _ := range tagSet {
+		allTagFields[k] = true
+	}
+	for k, v := range baseSet {
+		allTagFields[k] = v
+	}
+	for k, _ := range baseUnset {
+		allTagFields[k] = nil
+	}
+	qu.Debug("allTagFields===", allTagFields)
+	qu.Debug("tagSet===", tagSet)
+
+	if len(tagSet) >= 0 || baseInfo["purchasinglist_alltag"] != nil { //purchasinglist_alltag特殊处理
+		//1、更新数据源信息
+		setResult := map[string]interface{}{ //更新字段集
+			"i_updatetime": time.Now().Unix(),
+			"i_ckdata":     2,
+			"b_istag":      true,
+			"s_userid":     userId,
+			"s_groupid":    groupId,
+			//"b_isgiveuser":  true,
+			//"b_isgivegroup": true,
+			"s_login": username,
+		}
+		for field, val := range tagSet { //更新标注字段
+			setResult["v_taginfo."+field] = val
+		}
+		for field, val := range baseSet { //更新基本字段
+			setResult["v_baseinfo."+field] = val
+		}
+		baseUnsetResult := map[string]interface{}{} //删除字段集
+		for field, _ := range baseUnset {           //删除基本字段
+			baseUnsetResult["v_baseinfo."+field] = ""
+		}
+		set := map[string]interface{}{
+			"$set": setResult,
+		}
+		if len(baseUnsetResult) > 0 {
+			set["$unset"] = baseUnsetResult
+		}
+		qu.Debug("set---", set)
+		success = util.Mgo.UpdateById(sourceInfo, infoId, set)
+		//2、更新marked表
+		tmp, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1, "i_ckdata": 1})
+		qu.Debug("infoId:", infoId)
+		delete((*tmp), "_id")
+		(*tmp)["updatetime"] = time.Now().Unix()
+		b := util.Mgo.Update(util.AllToColl, map[string]interface{}{"_id": mgo.StringTOBsonId(infoId)}, map[string]interface{}{"$set": tmp}, true, false)
+		qu.Debug("Update Marked:", b)
+	}
+	/*
+		} else {
+			表示页面标注时未做修改标注
+		}
+	*/
+	//3、保存标注日志
+	project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"s_name": 1})
+	b := SaveLog(infoId, "", username, userId, userRole, qu.ObjToString((*project)["s_name"]), "标注", baseInfo, allTagFields)
+	qu.Debug("Save Log:", b)
+	f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
+}
+
+// UserDataMark 标注人员数据标注(基于任务的标注)
+func (f *Front) UserDataMark() {
+	defer qu.Catch()
+	success := false
+	msg := ""
+	user := f.GetSession("user").(map[string]interface{})
+	username := qu.ObjToString(user["s_login"]) //当前登录用户
+	userId := qu.ObjToString(user["id"])        //当前登录用户标识
+	userRole := qu.ObjToString(user["i_role"])  //当前登录用户权限
+
+	obj := []map[string]interface{}{}
+	infoId := f.GetString("s_infoid")
+	userTaskId := f.GetString("s_usertaskid")
+	qu.Debug("Task ID:", userTaskId, "	Data ID:", infoId)
+	data := f.GetString("data")
+	err := json.Unmarshal([]byte(data), &obj)
+	if err != nil {
+		qu.Debug("Json Unmarshal Error")
+		f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
+		return
+	}
+	tagSet := map[string]interface{}{}    //被标注字段状态
+	baseSet := map[string]interface{}{}   //要修改的字段信息
+	baseUnset := map[string]interface{}{} //要删除的字段信息
+	//isSaveMarked := false
+	if len(obj) == 1 { //单独保存某个一级
+		content, ok := obj[0]["content"].([]interface{})
+		if !ok || len(content) == 0 {
+			f.ServeJson(map[string]interface{}{"success": success, "msg": "解析数据失败"})
+			return
+		}
+		title := qu.ObjToString(obj[0]["title"])
+		istag, _ := obj[0]["checkAllTag"].(bool)
+		status := qu.IntAll(obj[0]["status"])
+		switch title {
+		case "基本字段":
+			MarkBase(content, tagSet, baseSet, baseUnset)
+		case "时间地点":
+			MarkTimePlace(content, tagSet, baseSet, baseUnset)
+		case "标的信息":
+			MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
+		case "多包信息":
+			MarkPackage(content, tagSet, baseSet, baseUnset, status)
+		case "中标候选人信息":
+			MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
+		case "其余信息":
+			MarkOther(content, tagSet, baseSet, baseUnset)
+		}
+	} else {
+		for j, val := range obj {
+			content, ok := val["content"].([]interface{})
+			status := qu.IntAll(val["status"])
+			if !ok {
+				qu.Debug("Content Error")
+				continue
+			}
+			istag, _ := val["checkAllTag"].(bool)
+			if j == 0 { //基本信息
+				MarkBase(content, tagSet, baseSet, baseUnset)
+			} else if j == 1 { //时间地点
+				MarkTimePlace(content, tagSet, baseSet, baseUnset)
+			} else if j == 2 { //标的物
+				MarkPurchasinglist(content, tagSet, baseSet, baseUnset, istag, status)
+			} else if j == 3 { //多包
+				MarkPackage(content, tagSet, baseSet, baseUnset, status)
+			} else if j == 4 { //候选人
+				MarkWonderorder(content, tagSet, baseSet, baseUnset, status)
+			} else { //其余信息
+				MarkOther(content, tagSet, baseSet, baseUnset)
+			}
+		}
+	}
+	//
+	userTask, _ := util.Mgo.FindById(util.TASKCOLLNAME, userTaskId, map[string]interface{}{"s_personid": 1, "s_personname": 1, "s_projectname": 1, "s_sourceinfo": 1})
+	if userTask == nil || len(*userTask) == 0 {
+		f.ServeJson(map[string]interface{}{"success": success, "msg": "查询用户任务失败"})
+		return
+	}
+	sourceInfo := qu.ObjToString((*userTask)["s_sourceinfo"])                                                     //数据源表
+	dataInfo, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1}) //查询标注保存前的原始信息
+	tagInfo, _ := (*dataInfo)["v_taginfo"].(map[string]interface{})
+	baseInfo, _ := (*dataInfo)["v_baseinfo"].(map[string]interface{})
+	if tagInfo != nil && len(tagInfo) > 0 {
+		for field, tmpStatus := range tagSet { //比对本次标注信息和历史标注信息
+			status := qu.IntAll(tmpStatus)            //此次被标注字段的状态
+			markedStatus := qu.IntAll(tagInfo[field]) //历史标注状态
+			if status == 1 && markedStatus != 0 {     //此次标注结果为正确,且有历史标注记录,不做修改
+				qu.Debug("已标注字段field---", field)
+				delete(tagSet, field)
+				delete(baseSet, field)
+				//continue
+			}
+			//else {
+			//	qu.Debug("未标注字段field---", field, status)
+			//}
+		}
+	}
+	//
+	allTagFields := map[string]interface{}{} //记录此此标注所有标注信息,用于日志记录
+	for k, _ := range tagSet {
+		allTagFields[k] = true
+	}
+	for k, v := range baseSet {
+		allTagFields[k] = v
+	}
+	for k, _ := range baseUnset {
+		allTagFields[k] = nil
+	}
+	qu.Debug("allTagFields===", allTagFields)
+	qu.Debug("tagSet===", tagSet)
+	if len(tagSet) >= 0 || baseInfo["purchasinglist_alltag"] != nil { //purchasinglist_alltag特殊处理
+		//1、更新数据源信息
+		setResult := map[string]interface{}{ //更新字段集
+			"i_updatetime": time.Now().Unix(),
+			"i_ckdata":     2,
+			"b_istag":      true,
+		}
+		for field, val := range tagSet { //更新标注字段
+			setResult["v_taginfo."+field] = val
+		}
+		for field, val := range baseSet { //更新基本字段
+			setResult["v_baseinfo."+field] = val
+			baseInfo[field] = val
+		}
+		baseUnsetResult := map[string]interface{}{} //删除字段集
+		for field, _ := range baseUnset {           //删除基本字段
+			baseUnsetResult["v_baseinfo."+field] = ""
+			delete(baseInfo, field)
+		}
+		ex, exp := DataException(baseInfo)
+		if ex != "" {
+			setResult["s_excp"] = ex
+			setResult["s_excp_info"] = exp
+		}
+		set := map[string]interface{}{
+			"$set": setResult,
+		}
+		if len(baseUnsetResult) > 0 {
+			set["$unset"] = baseUnsetResult
+		}
+		qu.Debug("set---", set)
+		success = util.Mgo.UpdateById(sourceInfo, infoId, set)
+		//2、更新marked表
+		tmp, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1, "i_ckdata": 1})
+		qu.Debug("infoId:", infoId)
+		delete((*tmp), "_id")
+		(*tmp)["updatetime"] = time.Now().Unix()
+		b := util.Mgo.Update(util.AllToColl, map[string]interface{}{"_id": mgo.StringTOBsonId(infoId)}, map[string]interface{}{"$set": tmp}, true, false)
+		qu.Debug("Update Marked:", b)
+	}
+	/*
+		} else {
+			表示页面标注时未做修改标注
+		}
+	*/
+	//3、修改任务状态
+	b := util.Mgo.Update(util.TASKCOLLNAME, map[string]interface{}{"_id": (*userTask)["_id"], "s_status": "未开始"}, map[string]interface{}{
+		"$set": map[string]interface{}{
+			"i_starttime":    time.Now().Unix(),
+			"i_updatetime":   time.Now().Unix(),
+			"s_updateperson": username,
+			"s_status":       "进行中",
+		},
+	}, false, false)
+	qu.Debug("Update UserTask:", b)
+	//4、保存标注日志
+	b = SaveLog(infoId, userTaskId, username, userId, userRole, qu.ObjToString((*userTask)["s_projectname"]), "标注", baseInfo, allTagFields)
+	qu.Debug("Save Log:", b)
+	f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
+}
+
+// MarkBase 标注基本信息
+func MarkBase(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}) {
+	defer qu.Catch()
+	info, _ := content[0].(map[string]interface{})
+	if uInputs, ok := info["uInput"].([]interface{}); ok {
+		for _, tmp := range uInputs {
+			if tmpMap, ok := tmp.(map[string]interface{}); ok {
+				if status := qu.IntAll(tmpMap["status"]); status != -1 {
+					key := qu.ObjToString(tmpMap["key"]) //字段
+					if key == "" {
+						continue
+					}
+					if status == 2 { //新增、修改、删除
+						input := tmpMap["input"]                                                                                               //值
+						if key == "bidamounttype" || key == "subtype" || key == "attach_discern" || key == "attach_ext" || key == "isrepeat" { //附件识别、抽取select
+							input = tmpMap["select"]
+						}
+						if input == "" { //删除原字段
+							baseUnset[key] = ""
+						} else { //修改原字段
+							if key == "budget" || key == "bidamount" || key == "biddiscount" {
+								input = qu.Float64All(input)
+								//input, _ = strconv.ParseFloat(qu.ObjToString(input), 32)
+							}
+							if key == "subtype" {
+								if topsubtype := strings.Split(qu.ObjToString(input), "-"); len(topsubtype) == 2 {
+									baseSet["toptype"] = topsubtype[0]
+									baseSet[key] = topsubtype[1]
+								}
+							} else if key == "s_winner" {
+								if strings.Contains(qu.ObjToString(input), ",") {
+									baseSet[key] = strings.ReplaceAll(qu.ObjToString(input), ",", ",")
+								} else {
+									baseSet[key] = input
+								}
+							} else {
+								baseSet[key] = input
+							}
+						}
+					}
+					tagSet[key] = status //记录被标注状态
+				}
+			}
+		}
+	}
+	qu.Debug("tagSet===", tagSet)
+	qu.Debug("baseSet===", baseSet)
+	qu.Debug("baseUnset===", baseUnset)
+}
+
+// MarkTimePlace 标注时间地点
+func MarkTimePlace(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}) {
+	info, _ := content[0].(map[string]interface{})
+	if uInputs, ok := info["uInput"].([]interface{}); ok {
+		for _, tmp := range uInputs {
+			if tmpMap, ok := tmp.(map[string]interface{}); ok {
+				if status := qu.IntAll(tmpMap["status"]); status != -1 {
+					key := qu.ObjToString(tmpMap["key"]) //字段
+					if key == "" {
+						continue
+					}
+					if status == 2 { //新增、修改、删除
+						input := tmpMap["input"] //值
+						if input == "" {
+							baseUnset[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)
+							}
+							baseSet[key] = input
+						}
+					}
+					tagSet[key] = status
+				}
+			}
+		}
+	}
+	qu.Debug("tagSet===", tagSet)
+	qu.Debug("baseSet===", baseSet)
+	qu.Debug("baseUnset===", baseUnset)
+}
+
+// MarkPurchasinglist 标注标的信息
+func MarkPurchasinglist(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}, istag bool, status int) {
+	if status == -1 {
+		return
+	}
+	baseSet["purchasinglist_alltag"] = istag //标的信息是否标注完全
+	purchasinglist := []interface{}{}
+	delpclson := 0
+	for _, con := range content {
+		info, _ := con.(map[string]interface{})
+		isNew, _ := info["isnew"].(bool) //是否是新增子包
+		pclSonStatus := qu.IntAll(info["status"])
+		if pclSonStatus == 4 {
+			delpclson++
+		}
+		if uInputs, ok := info["uInput"].([]interface{}); ok {
+			result := map[string]interface{}{
+				"isnew": isNew,
+			}
+			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 input == "" { //判断前台页面是否填值,无值不进行字段存储
+						isNull = true
+					} else if key == "number" || key == "unitprice" || key == "totalprice" {
+						input = qu.Float64All(input)
+					}
+					if !isNull { //避免数字类型的字段在没有填写值的情况默认给0
+						result[key] = input
+					}
+				}
+			}
+			if pclSonStatus != -1 { //没有标注的标的信息不打标记
+				result["purchasinglist_son"] = pclSonStatus
+			}
+			if len(result) > 0 && pclSonStatus != 4 {
+				purchasinglist = append(purchasinglist, result)
+			}
+		}
+	}
+	qu.Debug("purchasinglist", len(purchasinglist))
+	if len(purchasinglist)+delpclson == len(content) {
+		if len(purchasinglist) > 0 {
+			baseSet["purchasinglist"] = purchasinglist
+		} else if len(content) > 0 && delpclson == len(content) { //只有删除
+			baseUnset["purchasinglist"] = ""
+		}
+		tagSet["purchasinglist"] = status
+	} else {
+		qu.Debug("Purchasinglist Tag Error")
+	}
+	qu.Debug("tagSet===", tagSet)
+	qu.Debug("baseSet===", baseSet)
+	qu.Debug("baseUnset===", baseUnset)
+}
+
+// MarkPackage 标注多包信息
+func MarkPackage(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}, status int) {
+	if status == -1 {
+		return
+	}
+	pkgs := map[string]interface{}{}
+	newNum := 1
+	delpkgson := 0 //记录子包删除个数
+	for _, con := range content {
+		info, _ := con.(map[string]interface{})
+		pkgSonStatus := qu.IntAll(info["status"])
+		if pkgSonStatus == 4 {
+			delpkgson++
+		}
+		num := fmt.Sprint(info["num"])   //包号
+		isNew, _ := info["isnew"].(bool) //是否是新增子包
+		if isNew {                       //新增子包新建包名
+			num = "new" + fmt.Sprint(newNum)
+			newNum++
+		}
+		if uInputs, ok := info["uInput"].([]interface{}); ok {
+			result := map[string]interface{}{
+				"isnew": isNew,
+			}
+			winnerArr := []interface{}{}
+			bidamountArr := []interface{}{}
+			for _, tmp := range uInputs {
+				if tmpMap, ok := tmp.(map[string]interface{}); ok {
+					key := qu.ObjToString(tmpMap["key"]) //字段
+					input := tmpMap["input"]             //值
+					isNull := false                      //记录字段是否有值
+					if key == "bidamounttype" {
+						input = tmpMap["select"]
+					} else {
+						if input == "" { //判断前台页面是否填值,无值不进行字段存储
+							isNull = true
+						} else if key == "bidamount" || key == "budget" {
+							input = qu.Float64All(input)
+							//input, _ = strconv.ParseFloat(qu.ObjToString(input), 32)
+						}
+					}
+					if key == "winner" {
+						if isNull {
+							winnerArr = append(winnerArr, nil)
+						} else {
+							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
+					}
+				}
+			}
+			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(winner_all) > 0 {
+				result["winner_all"] = winner_all
+			}
+			result["package_son"] = pkgSonStatus
+
+			if len(result) > 0 && pkgSonStatus != 4 { //要删除的子包不再保存
+				pkgs[num] = result
+			}
+		}
+	}
+	qu.Debug("pkgs", len(pkgs))
+	if len(pkgs)+delpkgson == len(content) {
+		if len(pkgs) > 0 {
+			baseSet["package"] = pkgs
+		} else if len(content) > 0 && delpkgson == len(content) { //只有删除
+			baseUnset["package"] = ""
+		}
+		tagSet["package"] = status
+	} else {
+		qu.Debug("Package Tag Error")
+	}
+}
+
+//标注中标候选人信息
+func MarkWonderorder(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}, status int) {
+	if status == -1 {
+		return
+	}
+	winnerorder := []interface{}{}
+	delwodrson := 0
+	for _, con := range content {
+		info, _ := con.(map[string]interface{})
+		isNew, _ := info["isnew"].(bool) //是否是新增子包
+		wodrSonStatus := qu.IntAll(info["status"])
+		if wodrSonStatus == 4 {
+			delwodrson++
+		}
+		if uInputs, ok := info["uInput"].([]interface{}); ok {
+			result := map[string]interface{}{
+				"isnew": isNew,
+			}
+			for _, tmp := range uInputs {
+				if tmpMap, ok := tmp.(map[string]interface{}); ok {
+					key := qu.ObjToString(tmpMap["key"]) //字段
+					input := tmpMap["input"]             //值
+					isNull := false
+					if input == "" { //判断前台页面是否填值,无值不进行字段存储
+						isNull = true
+					} else if key == "price" {
+						input = qu.Float64All(input)
+						//input, _ = strconv.ParseFloat(qu.ObjToString(input), 32)
+					}
+					if !isNull { //避免数字类型的字段在没有填写值的情况默认给0
+						result[key] = input
+					}
+					result["winnerorder_son"] = wodrSonStatus
+				}
+			}
+			if len(result) > 0 && wodrSonStatus != 4 {
+				winnerorder = append(winnerorder, result)
+			}
+		}
+	}
+	qu.Debug("winnerorder", len(winnerorder))
+	if len(winnerorder)+delwodrson == len(content) {
+		if len(winnerorder) > 0 {
+			baseSet["winnerorder"] = winnerorder
+		} else if len(content) > 0 && delwodrson == len(content) { //只有删除
+			baseUnset["winnerorder"] = ""
+		}
+		tagSet["winnerorder"] = status
+	} else {
+		qu.Debug("Winnerorder Tag Error")
+	}
+	qu.Debug("tagSet===", tagSet)
+	qu.Debug("baseSet===", baseSet)
+	qu.Debug("baseUnset===", baseUnset)
+}
+
+//标注其他信息
+func MarkOther(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}) {
+	info, _ := content[0].(map[string]interface{})
+	if uInputs, ok := info["uInput"].([]interface{}); ok {
+		for _, tmp := range uInputs {
+			if tmpMap, ok := tmp.(map[string]interface{}); ok {
+				if status := qu.IntAll(tmpMap["status"]); status != -1 {
+					key := qu.ObjToString(tmpMap["key"]) //字段
+					if key == "" {
+						continue
+					}
+					if status == 2 { //新增、修改、删除
+						input := tmpMap["input"] //值
+						if key == "isppp" || key == "contract_guarantee" || key == "bid_guarantee" {
+							input = tmpMap["select"]
+						}
+						if input == "" {
+							baseUnset[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" ||
+								key == "biddiscount" {
+								input = qu.Float64All(input)
+								//input, _ = strconv.ParseFloat(qu.ObjToString(input), 32)
+							}
+							baseSet[key] = input
+						}
+					}
+					tagSet[key] = status
+				}
+			}
+		}
+	}
+	qu.Debug("tagSet===", tagSet)
+	qu.Debug("baseSet===", baseSet)
+	qu.Debug("baseUnset===", baseUnset)
+}
+
+// SaveLog 标注日志保存
+func SaveLog(s_infoid, s_usertaskid, username, userid, role, projectname, s_stype string, baseInfo, allTagFields map[string]interface{}) (success bool) {
+	defer qu.Debug()
+	v_before := map[string]interface{}{}
+	for f, v := range allTagFields {
+		if _, ok := v.(bool); ok && f != "purchasinglist_alltag" { //表示此次标注status=1的字段
+			allTagFields[f] = baseInfo[f]
+		}
+		v_before[f] = baseInfo[f]
+	}
+	save := map[string]interface{}{
+		"s_projectname": projectname,
+		"s_taskid":      s_usertaskid,
+		"s_infoid":      s_infoid,
+		"s_stype":       s_stype,
+		"s_userid":      userid,
+		"s_role":        role,
+		"s_username":    username,
+		"i_createtime":  time.Now().Unix(),
+		"v_before":      v_before,
+		"v_after":       allTagFields,
+	}
+	id := util.Mgo.Save(util.LOGCOLLNAME, save)
+	if id != "" {
+		success = true
+	}
+	return
+}
+
+func (f *Front) CheckDataPurchase() {
+	defer qu.Catch()
+	if f.Method() == "POST" {
+		datatype, _ := f.GetInteger("datatype")
+		stype := f.GetString("stype")
+		sourceinfo := f.GetString("s_sourceinfo")
+		tid := f.GetString("taskid")
+		keyword := f.GetString("keyword")
+		keyword = strings.ReplaceAll(keyword, ",", ",")
+		keyArr := strings.Split(keyword, ",")
+		query := make(map[string]interface{})
+		if tid != "" {
+			query["b_istag"] = true
+			if stype == "group" {
+				query["s_grouptaskid"] = tid
+			} else {
+				query["s_usertaskid"] = tid
+			}
+		} else {
+			if stype == "notag" {
+				query["b_istagging"] = false
+				if datatype == 1 {
+					// 待分发数据
+					query["b_isgivegroup"] = false
+				} else {
+					// 已分发 标注数据
+					query["b_istag"] = true
+					query["b_isgivegroup"] = true
+				}
+			} else if stype == "tag" { //未达标
+				query["b_istagging"] = true
+				query["i_ckdata"] = 2
+			} else {
+				query["i_ckdata"] = 2
+			}
+		}
+		query["v_baseinfo.purchasinglist"] = map[string]interface{}{"$exists": true}
+		count := util.Mgo.Count(sourceinfo, query)
+		qu.Debug(query, count)
+		info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, `{"v_baseinfo": 1, "b_isEff": 1}`, false, -1, -1)
+		var updateArr [][]map[string]interface{}
+		for _, m := range *info {
+			baseinfo := m["v_baseinfo"].(map[string]interface{})
+			purs := baseinfo["purchasinglist"].([]interface{})
+			if len(purs) > 0 {
+				arr1 := []map[string]interface{}{} //质检通过
+				arr2 := []map[string]interface{}{} //质检未通过
+				for _, m2 := range qu.ObjArrToMapArr(purs) {
+					if validPurchase(keyArr, qu.ObjToString(m2["itemname"])) {
+						m2["b_isEff"] = true
+						if m["b_isEff"] != nil && !m["b_isEff"].(bool) {
+							m["b_isEff"] = true
+						}
+						arr1 = append(arr1, m2)
+					} else {
+						m2["b_isEff"] = false
+						arr2 = append(arr2, m2)
+					}
+				}
+				baseinfo["purchasinglist"] = append(arr1, arr2...)
+				var update []map[string]interface{}
+				update = append(update, map[string]interface{}{"_id": m["_id"]})
+				update = append(update, map[string]interface{}{"$set": m})
+				updateArr = append(updateArr, update)
+			}
+			if len(updateArr) > 500 {
+				tmps := updateArr
+				util.Mgo.UpdateBulk(sourceinfo, tmps...)
+				updateArr = [][]map[string]interface{}{}
+			}
+		}
+		if len(updateArr) > 0 {
+			qu.Debug(updateArr)
+			util.Mgo.UpSertBulk(sourceinfo, updateArr...)
+		}
+		f.ServeJson(map[string]interface{}{"success": true, "msg": ""})
+	}
+}
+
+func validPurchase(arr []string, str string) bool {
+	for _, s := range arr {
+		if strings.Contains(str, s) {
+			return true
+		}
+	}
+	return false
+}

+ 27 - 27
src/front/user.go

@@ -27,33 +27,33 @@ func (f *Front) Login() {
 		imgCode := f.GetString("imgCode")
 		passwordEn := qu.SE.EncodeString(password)
 		qu.Debug(username, passwordEn, imgCode)
-		session, err := store.Get(f.Request, "dataTagLoginImgCode")
-		if err != nil {
-			qu.Debug("图片验证码session获取失败-%s \n", username)
-			f.ServeJson(map[string]interface{}{
-				"code":    0,
-				"status":  false,
-				"message": "获取失败",
-			})
-			return
-		}
-		code := qu.ObjToString(session.Values["dataTagLoginImgCode"])
-		if code == "" {
-			qu.Debug("图片验证码过期-%s \n", username)
-			f.ServeJson(map[string]interface{}{
-				"checked": false,
-				"message": "图片验证码过期",
-			})
-			return
-		}
-		if !captcha.VerifyString(code, imgCode) {
-			qu.Debug("图片验证码错误-%s \n", username)
-			f.ServeJson(map[string]interface{}{
-				"checked": false,
-				"message": "图片验证码错误",
-			})
-			return
-		}
+		//session, err := store.Get(f.Request, "dataTagLoginImgCode")
+		//if err != nil {
+		//	qu.Debug("图片验证码session获取失败-%s \n", username)
+		//	f.ServeJson(map[string]interface{}{
+		//		"code":    0,
+		//		"status":  false,
+		//		"message": "获取失败",
+		//	})
+		//	return
+		//}
+		//code := qu.ObjToString(session.Values["dataTagLoginImgCode"])
+		//if code == "" {
+		//	qu.Debug("图片验证码过期-%s \n", username)
+		//	f.ServeJson(map[string]interface{}{
+		//		"checked": false,
+		//		"message": "图片验证码过期",
+		//	})
+		//	return
+		//}
+		//if !captcha.VerifyString(code, imgCode) {
+		//	qu.Debug("图片验证码错误-%s \n", username)
+		//	f.ServeJson(map[string]interface{}{
+		//		"checked": false,
+		//		"message": "图片验证码错误",
+		//	})
+		//	return
+		//}
 		query := map[string]interface{}{
 			"s_login":    username,
 			"s_password": passwordEn,

+ 54 - 39
src/util/config.go

@@ -14,31 +14,34 @@ import (
 //const JYDATATODB = "jyqyfw"
 
 var (
-	Sysconfig           map[string]interface{} //配置文件
-	Quaconfig           map[string]interface{} //质量配置文件
-	Es                  *elastic.Elastic
-	Mgo                 *mongodb.MongodbSim
-	AllToColl           string              //所有标注数据汇总表
-	Password            string              //默认登陆密码
-	MgoB                *mongodb.MongodbSim //bidding
-	BidColl1            string
-	BidColl2            string
-	MgoE                *mongodb.MongodbSim //extract
-	ExtColl1            string
-	ExtColl2            string
-	ProjectColl         string
-	MgoJy               *mongodb.MongodbSim //jy
-	JyHistory           string
-	JyUser              string
-	CustomerFieldMap_EH map[string]string
-	CustomerFieldMap_HE map[string]string
-	BiaoZhu             map[string]interface{}
-	PurchasinglistField []map[string]string
-	PackageField        []map[string]string
-	WinnerorderField    []map[string]string
-	AllFieldArr         []map[string]string
-	TopSubStypeArr      []string
-	TopSubStypeArr2     []string
+	Sysconfig            map[string]interface{} //配置文件
+	Quaconfig            map[string]interface{} //质量配置文件
+	Es                   *elastic.Elastic
+	Mgo                  *mongodb.MongodbSim
+	AllToColl            string              //所有标注数据汇总表
+	Password             string              //默认登陆密码
+	MgoB                 *mongodb.MongodbSim //bidding
+	BidColl1             string
+	BidColl2             string
+	MgoE                 *mongodb.MongodbSim //extract
+	ExtColl1             string
+	ExtColl2             string
+	ProjectColl          string
+	MgoJy                *mongodb.MongodbSim //jy
+	JyHistory            string
+	JyUser               string
+	CustomerFieldMap_EH  map[string]string
+	CustomerFieldMap_HE  map[string]string
+	BiaoZhu              map[string]interface{}
+	PurchasinglistField  []map[string]string
+	PurchasinglistField1 []map[string]string
+	PackageField         []map[string]string
+	WinnerorderField     []map[string]string
+	AllFieldArr          []map[string]string
+	TopSubStypeArr       []string
+	TopSubStypeArr2      []string
+	DataTypeArr          []string
+	DataTypeMap          map[string]interface{} //项目中数据类型
 )
 
 var (
@@ -52,20 +55,20 @@ var (
 
 var SE = qu.SimpleEncrypt{Key: "topJYBX2019"}
 var SourceInfoIndexArr = []mongo.IndexModel{
-	mongo.IndexModel{Keys: map[string]interface{}{"s_grouptaskid": 1}}, //独立索引
-	mongo.IndexModel{Keys: map[string]interface{}{"s_usertaskid": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"s_grouptaskid": 1, "b_istag": 1}}, //联合索引
-	mongo.IndexModel{Keys: map[string]interface{}{"s_grouptaskid": 1, "s_isgiveuser": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"s_usertaskid": 1, "b_istag": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"s_usertaskid": 1, "b_check": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"b_istagging": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"b_istagging": 1, "b_istag": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"b_isgivegroup": 1, "b_istagging": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1, "b_istag": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1, "b_istagging": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1, "i_ckdata": 1}},
-	mongo.IndexModel{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1, "i_ckdata": 1, "b_istagging": 1}},
+	{Keys: map[string]interface{}{"s_grouptaskid": 1}}, //独立索引
+	{Keys: map[string]interface{}{"s_usertaskid": 1}},
+	{Keys: map[string]interface{}{"s_grouptaskid": 1, "b_istag": 1}}, //联合索引
+	{Keys: map[string]interface{}{"s_grouptaskid": 1, "s_isgiveuser": 1}},
+	{Keys: map[string]interface{}{"s_usertaskid": 1, "b_istag": 1}},
+	{Keys: map[string]interface{}{"s_usertaskid": 1, "b_check": 1}},
+	{Keys: map[string]interface{}{"b_istagging": 1}},
+	{Keys: map[string]interface{}{"b_istagging": 1, "b_istag": 1}},
+	{Keys: map[string]interface{}{"b_isgivegroup": 1, "b_istagging": 1}},
+	{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1}},
+	{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1, "b_istag": 1}},
+	{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1, "b_istagging": 1}},
+	{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1, "i_ckdata": 1}},
+	{Keys: map[string]interface{}{"b_isgivegroup": 1, "s_isgiveuser": 1, "i_ckdata": 1, "b_istagging": 1}},
 }
 
 const JYHREFPRE = "https://www.jianyu360.cn/article/content/"
@@ -195,6 +198,14 @@ func InitConfig() {
 		descript := qu.ObjToString(tmp["descript"])
 		PurchasinglistField = append(PurchasinglistField, map[string]string{key: descript})
 	}
+	PurchasinglistField1 = []map[string]string{}
+	pcls1, _ := BiaoZhu["purchasinglist_1"].([]interface{})
+	for _, pcl := range pcls1 {
+		tmp := pcl.(map[string]interface{})
+		key := qu.ObjToString(tmp["key"])
+		descript := qu.ObjToString(tmp["descript"])
+		PurchasinglistField1 = append(PurchasinglistField1, map[string]string{key: descript})
+	}
 	PackageField = []map[string]string{}
 	pkgs, _ := BiaoZhu["package"].([]interface{})
 	for _, pkg := range pkgs {
@@ -220,6 +231,10 @@ func InitConfig() {
 		}
 	}
 	TopSubStypeArr2 = TopSubStypeArr
+	DataTypeMap = Sysconfig["dataType"].(map[string]interface{})
+	for k := range DataTypeMap {
+		DataTypeArr = append(DataTypeArr, k)
+	}
 
 	initQuaConfig()
 }

+ 26 - 13
src/web/templates/com/header.html

@@ -116,17 +116,30 @@
 <!-- /.modal -->
 <script>
 	$('#t_name').val({{(session "user").s_name}})
-function t_save(){
-	pwd=$("#t_pwd").val()
-	showConfirm("确定修改?", function() {
-		$.ajax({
-			url:"/front/updatepwd",
-			type:"post",
-			data:{"id":{{(session "user").id}},"pwd":pwd},
-			success:function(r){
-				$("#modal-topuserinfo").modal("hide");
-			}
-		})
-	});
-}
+
+	function t_save(){
+		pwd=$("#t_pwd").val()
+		showConfirm("确定修改?", function() {
+			$.ajax({
+				url:"/front/updatepwd",
+				type:"post",
+				data:{"id":{{(session "user").id}},"pwd":pwd},
+				success:function(r){
+					$("#modal-topuserinfo").modal("hide");
+				}
+			})
+		});
+	}
+
+	//展示loading框
+	showLoading = function (text){
+		if(text){
+			$("#loadText").html(text)
+		}
+		$('#loadingModal').modal({backdrop: 'static', keyboard: false});
+	}
+	//隐藏掉loading框
+	hideLoading = function (){
+		$('#loadingModal').modal('hide');
+	}
 </script>

+ 5 - 5
src/web/templates/login.html

@@ -98,7 +98,7 @@
             alert("账号和密码不能为空")
             return
         }
-        if ($("#verifyImgCode").val().trim().replace(/\s/g, "").length === 4) {
+        // if ($("#verifyImgCode").val().trim().replace(/\s/g, "").length === 4) {
             $.ajax({
                 url:"/",
                 type:"post",
@@ -121,10 +121,10 @@
                     }
                 }
             })
-        } else {
-            $("#verifyImg")[0].src = '/code?' + Math.random()
-            alert("图片验证码有误,请重填");
-        }
+        // } else {
+        //     $("#verifyImg")[0].src = '/code?' + Math.random()
+        //     alert("图片验证码有误,请重填");
+        // }
     }
 
 </script>

+ 135 - 41
src/web/templates/project/check_data_list.html

@@ -31,48 +31,71 @@
     <!-- Main content -->
     <section class="content">
         <div class="row">
-            <div class="col-xs-12">
-                <div class="box">
+            <div class="box">
+                <div class="box-body">
                     <div class="box-body">
-                        <div class="box-body">
-                            <h4><i class="glyphicon glyphicon-exclamation-sign" style="margin-right: 6px"></i>数据情况</h4>
-                            <div class="form-group" style="margin-left: 10px;margin-top: 10px">
-                                <div class="col-xs-5" style="width: auto">
-                                    <label class="form-inline">已标数据/数据总量:
-                                        <input type="text" class="form-control" style="width: 120px;padding: 5px" readonly value="{{.T.taskTagNum}} / {{ .T.taskNum }}"></label>
-                                    <label class="form-inline">已检数据/已标总量:
-                                        <input type="text" class="form-control" style="width: 120px;padding: 5px" readonly value="{{.T.taskCheckNum}} / {{ .T.taskTagNum }}"></label>
-                                </div>
-                                <input type="button" class="btn btn-primary" onclick="checkResult()" value="质检结果">
-                                <input type="button" class="btn btn-primary" onclick="checkExcpResult()" value="异常校验结果">
+                        <h4><i class="glyphicon glyphicon-exclamation-sign" style="margin-right: 6px"></i>数据情况</h4>
+                        <div class="form-group" style="margin-left: 10px;margin-top: 10px">
+                            <div class="col-xs-5" style="width: auto">
+                                <label class="form-inline">已标数据/数据总量:
+                                    <input type="text" class="form-control" style="width: 120px;padding: 5px" readonly value="{{.T.taskTagNum}} / {{ .T.taskNum }}"></label>
+                                <label class="form-inline">已检数据/已标总量:
+                                    <input type="text" class="form-control" style="width: 120px;padding: 5px" readonly value="{{.T.taskCheckNum}} / {{ .T.taskTagNum }}"></label>
                             </div>
+                            <input type="button" class="btn btn-primary" onclick="checkResult()" value="质检结果">
+                            <input type="button" class="btn btn-primary" onclick="checkExcpResult()" value="异常校验结果">
                         </div>
-
-                        <div id="status-div" class="col-xs-1" style="width: auto;float:right;">
-                            <label for="statusSelect">质检状态:
-                                <select class="form-control selectpicker" id="statusSelect">
-                                    <option value="0">全部</option>
-                                    <option value="1">已质检</option>
-                                    <option value="-1">未质检</option>
-                                </select></label>
-                            <label for="dataSelect">数据状态:
-                                <select class="form-control selectpicker" id="dataSelect">
-                                    <option value="0">全部</option>
-                                    <option value="1">正常</option>
-                                    <option value="-1" selected>异常</option>
-                                </select></label>
+                        <div class="col-xs-10" style="margin-left: 10px;margin-top: 10px">
+                            <label class="form-inline">标的物关键词校验:
+                                <input type="text" id="purchase" class="form-control" style="width: 420px;padding: 5px" value="">
+                            </label>
+                            <input type="button" class="btn btn-primary" onclick="validPurchase()" style="margin-left: 10px" value="标的物有效性校验">
                         </div>
-                        <table id="dataTable" class="table table-bordered table-hover">
-                            <thead>
-                            <tr>
-                                <th></th>
-                                <th>数据状态</th>
-                                <th>标题</th>
-                                <th>用户</th>
-                            </tr>
-                            </thead>
-                        </table>
                     </div>
+                    <div id="status-div" class="col-xs-1" style="width: auto;float: right;">
+                        <label for="typeSelect" class="form-inline">类型:
+                            <select class="form-control selectpicker" id="typeSelect">
+                                <option value="-1">全部</option>
+                            </select></label>
+                        <label for="fieldSelect" class="form-inline">字段:
+                            <select class="form-control selectpicker" id="fieldSelect">
+                                <option value="-1">未选择</option>
+                            </select></label>
+                        <label id="moneyInput" class="form-inline" style="display: none">
+                            <input type="number" id="minInput" class="form-control" style="width: 70px;padding: 5px" placeholder="最小值">
+                            <input type="number" id="maxInput" class="form-control" style="width: 70px;padding: 5px" placeholder="最大值">
+                        </label>
+                        <label id="fieldStatus1" class="form-inline" style="display: none;padding-left: 10px">
+                            <input type="checkbox" id="field-exist"> 不存在</label>
+                        <label class="form-inline" id="fieldStatus2" style="display: none;padding-left: 10px">
+                            <input type="checkbox" id="field-tag"> 未标注</label>
+                        <label class="form-inline" id="search-btn" style="padding-left: 10px;display: none">
+                            <input type="button" class="btn btn-sm btn-default" value="搜索" onclick="searchBtn()">
+                        </label>
+                        <label for="statusSelect" class="form-inline">质检状态:
+                            <select class="form-control selectpicker" id="statusSelect">
+                                <option value="0">全部</option>
+                                <option value="1">已质检</option>
+                                <option value="-1">未质检</option>
+                            </select></label>
+                        <label for="dataSelect" class="form-inline">数据状态:
+                            <select class="form-control selectpicker" id="dataSelect">
+                                <option value="0">全部</option>
+                                <option value="1">正常</option>
+                                <option value="-1" selected>异常</option>
+                            </select>
+                        </label>
+                    </div>
+                    <table id="dataTable" class="table table-bordered table-hover">
+                        <thead>
+                        <tr>
+                            <th></th>
+                            <th>数据状态</th>
+                            <th>标题</th>
+                            <th>用户</th>
+                        </tr>
+                        </thead>
+                    </table>
                 </div>
             </div>
         </div>
@@ -104,12 +127,14 @@
     let sourceinfo = {{ .T.sourceinfo }}
     let stype = {{ .T.stype }}
     let datatype = {{ .T.datatype }}
+    let topsubtype = {{ .T.topsubtype }}
+    let allfield = {{ .T.allfield }}
 
     $(function () {
         ttable = $('#dataTable').dataTable({
             "paging": true,
             "lengthChange": false,
-            "searching": true,
+            "searching": false,
             "processing": true,
             // "pageLength": 20,
             "ordering": false,
@@ -117,8 +142,8 @@
             "autoWidth": false,
             "serverSide": true,
             "ajax": {
-                "url": "/front/user/check/data",
-                "type": "post",
+                "url": "/front/jy/check/data",
+                "type": "POST",
                 "data": {"tid": tid, "s_sourceinfo": sourceinfo, "stype": stype, "datatype": datatype}
             },
             "language": {
@@ -161,19 +186,66 @@
             ],
             "initComplete": function () {
                 $("#dataTable_filter").append($('#status-div'))
-                $("[type=search]").attr('placeholder', "标题")
             },
             "fnServerParams": function (e) {
                 e.s_status = $("#statusSelect option:selected").val()
                 e.s_excp = $("#dataSelect option:selected").val()
+                e.datatype1 = $("#typeSelect option:selected").val()
+                e.field = $("#fieldSelect option:selected").val()
+                if (e.field !== "-1") {
+                    e.hasno = $("#field-exist").is(':checked')
+                    e.notag = $("#field-tag").is(':checked')
+                    if (e.field === "budget" || e.field === "bidamount") {
+                        e.minval = $('#minInput').val()
+                        e.maxval = $('#maxInput').val()
+                    }
+                }
             }
         });
+        for (let i in topsubtype) {
+            let opt = document.createElement('option');
+            opt.innerText = topsubtype[i];
+            opt.value = topsubtype[i];
+            $('#typeSelect')[0].appendChild(opt)
+        }
+        $("#typeSelect").selectpicker("refresh");
+        for (let i in allfield) {
+            for (let key in allfield[i]) {
+                let opt = document.createElement('option');
+                opt.innerText = allfield[i][key];
+                opt.value = key;
+                $('#fieldSelect')[0].appendChild(opt)
+            }
+        }
+        $("#fieldSelect").selectpicker("refresh");
         $('#statusSelect').on('changed.bs.select', function () {
             ttable.api().ajax.reload();
         })
         $('#dataSelect').on('changed.bs.select', function () {
             ttable.api().ajax.reload();
         })
+        $('#typeSelect').on('changed.bs.select', function () {
+            ttable.api().ajax.reload();
+        })
+        $('#fieldSelect').on('changed.bs.select', function () {
+            // ttable.api().ajax.reload();
+            let v = $("#fieldSelect option:selected").val()
+            if (v !== "-1") {
+                $('#fieldStatus1').show()
+                $('#fieldStatus2').show()
+                $('#search-btn').show()
+                if (v === "budget" || v === "bidamount") {
+                    $('#moneyInput').show()
+                }else {
+                    $('#moneyInput').hide()
+                }
+            }else {
+                ttable.api().ajax.reload();
+                $('#search-btn').hide()
+                $('#fieldStatus1').hide()
+                $('#fieldStatus2').hide()
+            }
+        })
     });
 
     function checkResult() {
@@ -187,4 +259,26 @@
     function checkExcpResult() {
         window.location.href = "/front/check/excp/result?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype={{.T.stype}}&datatype={{.T.datatype}}"
     }
+
+    function validPurchase() {
+        const ps = $("#purchase").val()
+        if (ps === "") {
+            showTip("关键词不能为空")
+            return
+        }
+        showLoading("正在校验数据,请稍候...")
+        $.ajax({
+            url: "/front/check/data/purchase",
+            type: 'POST',
+            data: {"s_sourceinfo": sourceinfo, "taskid": tid, "datatype": datatype, "keyword": ps},
+            success: function (r) {
+                hideLoading()
+                if (r.success) {
+                    // location.reload()
+                } else {
+                    showTip(r.msg);
+                }
+            }
+        })
+    }
 </script>

+ 3 - 3
src/web/templates/project/check_excp_result.html

@@ -8,17 +8,17 @@
         <h1><small></small></h1>
         <ol class="breadcrumb" name="tab1" style="display: none">
             <li><a href="/front/project"><i class="fa fa-dashboard"></i> 项目列表</a></li>
-            <li><a href="/front/user/check/data?pid={{.T.pid}}&s_sourceinfo={{.T.sourceinfo}}"><i class="fa fa-dashboard"></i> 质检列表</a></li>
+            <li><a href="/front/jy/check/data?pid={{.T.pid}}&s_sourceinfo={{.T.sourceinfo}}"><i class="fa fa-dashboard"></i> 质检列表</a></li>
             <li><a href="#"><i class="fa fa-dashboard"></i> 异常校验结果</a></li>
         </ol>
         <ol class="breadcrumb" name="tab2" style="display: none">
             <li><a href="/front/group/admin/task/list"><i class="fa fa-dashboard"></i> 剑鱼任务列表</a></li>
-            <li><a href="/front/user/check/data?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype=group"><i class="fa fa-dashboard"></i> 质检列表</a></li>
+            <li><a href="/front/jy/check/data?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype=group"><i class="fa fa-dashboard"></i> 质检列表</a></li>
             <li><a href="#"><i class="fa fa-dashboard"></i> 异常校验结果</a></li>
         </ol>
         <ol class="breadcrumb" name="tab3" style="display: none">
             <li><a href="/front/group/task/list"><i class="fa fa-dashboard"></i> 用户组任务列表</a></li>
-            <li><a href="/front/user/check/data?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype=group"><i class="fa fa-dashboard"></i> 质检列表</a></li>
+            <li><a href="/front/jy/check/data?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype=group"><i class="fa fa-dashboard"></i> 质检列表</a></li>
             <li><a href="#"><i class="fa fa-dashboard"></i> 异常校验结果</a></li>
         </ol>
         <ol class="breadcrumb" name="tab4" style="display: none">

+ 2 - 2
src/web/templates/project/check_result.html

@@ -8,12 +8,12 @@
         <h1><small></small></h1>
         <ol class="breadcrumb" name="tab1" style="display: none">
             <li><a href="/front/project"><i class="fa fa-dashboard"></i> 项目列表</a></li>
-            <li><a href="/front/user/check/data?pid={{.T.pid}}&s_sourceinfo={{.T.sourceinfo}}"><i class="fa fa-dashboard"></i> 质检列表</a></li>
+            <li><a href="/front/jy/check/data?pid={{.T.pid}}&s_sourceinfo={{.T.sourceinfo}}"><i class="fa fa-dashboard"></i> 质检列表</a></li>
             <li><a href="#"><i class="fa fa-dashboard"></i> 质检结果</a></li>
         </ol>
         <ol class="breadcrumb" name="tab2" style="display: none">
             <li><a href="/front/group/admin/task/list"><i class="fa fa-dashboard"></i> 剑鱼任务列表</a></li>
-            <li><a href="/front/user/check/data?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype=group"><i class="fa fa-dashboard"></i> 质检列表</a></li>
+            <li><a href="/front/jy/check/data?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype=group"><i class="fa fa-dashboard"></i> 质检列表</a></li>
             <li><a href="#"><i class="fa fa-dashboard"></i> 质检结果</a></li>
         </ol>
         <ol class="breadcrumb" name="tab3" style="display: none">

+ 0 - 1
src/web/templates/project/check_task_list.html

@@ -134,7 +134,6 @@
 
     function checkMethod(tid, pid, sourceinfo, status) {
         if (status !== "已关闭") {
-            sessionStorage.setItem("check", "task")
             window.location.href = "/front/user/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=user"
         }else {
             showTip("操作不允许")

+ 153 - 0
src/web/templates/project/check_user_data_list.html

@@ -0,0 +1,153 @@
+{{include "com/inc.html"}}
+<!-- Main Header -->
+{{include "com/header.html"}}
+<!-- Left side column. 权限菜单 -->
+{{include "com/menu.html"}}
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1><small></small></h1>
+        <ol class="breadcrumb">
+            <li><a href="/front/user/check/list"><i class="fa fa-dashboard"></i> 质检任务列表</a></li>
+            <li><a href="#"><i class="fa fa-dashboard"></i> 质检列表</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="row">
+            <div class="box">
+                <div class="box-body">
+                    <div class="box-body">
+                        <h4><i class="glyphicon glyphicon-exclamation-sign" style="margin-right: 6px"></i>数据情况</h4>
+                        <div class="form-group" style="margin-left: 10px;margin-top: 10px">
+                            <div class="col-xs-5" style="width: auto">
+                                <label class="form-inline">已标数据/数据总量:
+                                    <input type="text" class="form-control" style="width: 120px;padding: 5px" readonly value="{{.T.taskTagNum}} / {{ .T.taskNum }}"></label>
+                                <label class="form-inline">已检数据/已标总量:
+                                    <input type="text" class="form-control" style="width: 120px;padding: 5px" readonly value="{{.T.taskCheckNum}} / {{ .T.taskTagNum }}"></label>
+                            </div>
+                            <input type="button" class="btn btn-primary" onclick="checkResult()" value="质检结果">
+                            <input type="button" class="btn btn-primary" onclick="checkExcpResult()" value="异常校验结果">
+                        </div>
+                    </div>
+                    <div id="status-div" class="col-xs-1" style="width: auto;float: right;">
+                        <label for="statusSelect" class="form-inline">质检状态:
+                            <select class="form-control selectpicker" id="statusSelect">
+                                <option value="0">全部</option>
+                                <option value="1">已质检</option>
+                                <option value="-1">未质检</option>
+                            </select></label>
+                        <label for="dataSelect" class="form-inline">数据状态:
+                            <select class="form-control selectpicker" id="dataSelect">
+                                <option value="0">全部</option>
+                                <option value="1">正常</option>
+                                <option value="-1" selected>异常</option>
+                            </select>
+                        </label>
+                    </div>
+                    <table id="dataTable" class="table table-bordered table-hover">
+                        <thead>
+                        <tr>
+                            <th></th>
+                            <th>数据状态</th>
+                            <th>标题</th>
+                            <th>用户</th>
+                        </tr>
+                        </thead>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+{{include "com/footer.html"}}
+<script>
+    menuActive("/front/user/check/list");
+
+    let tid = {{ .T.tid }}
+    let pid = {{ .T.pid }}
+    let sourceinfo = {{ .T.sourceinfo }}
+
+    $(function () {
+        ttable = $('#dataTable').dataTable({
+            "paging": true,
+            "lengthChange": false,
+            "searching": false,
+            "processing": true,
+            // "pageLength": 20,
+            "ordering": false,
+            "info": true,
+            "autoWidth": false,
+            "serverSide": true,
+            "ajax": {
+                "url": "/front/user/check/data",
+                "type": "POST",
+                "data": {"tid": tid, "s_sourceinfo": sourceinfo}
+            },
+            "language": {
+                "url": "/dist/js/dataTables.chinese.lang"
+            },
+            "fnDrawCallback": function () {
+                $("ul.pagination").prepend("&nbsp;&nbsp;&nbsp;转到第 <input type='text' id='changePage'   style='width:20px;'> 页    <a type='text' href='javascript:void(0);' id='dataTable-btn' style='text-align:center'>GO</a>");
+                $('#dataTable-btn').click(function (e) {
+                    var redirectpage = 0
+                    if ($("#changePage").val() && $("#changePage").val() > 0) {
+                        var redirectpage = $("#changePage").val() - 1;
+                    }
+                    ttable.api().page(redirectpage).draw(false);
+                });
+                this.api().column(0).nodes().each(function (cell, i) {
+                    cell.innerHTML = i + 1;
+                });
+            },
+            "columns": [
+                {"data": null, width: "2%"},
+                {"data": "s_excp", width: "5%", render: function (val) {
+                        let tmp;
+                        if (val !== undefined && val !== "") {
+                            tmp = '<span style="display: inline-block;font-size:14px;">异常</span>'
+                        } else {
+                            tmp = '<span style="display: inline-block;font-size:14px;">正常</span>'
+                        }
+                        return tmp
+                    }},
+                {"data": "v_baseinfo.title", render: function (val, index, row) {
+                        let tmp
+                        if (row["b_check"]) {
+                            tmp = '<a style="display: inline-block;cursor:pointer;font-size:16px;color: green" target="_blank" href="/front/user/check/detail/?pid='+pid+'&did='+row._id+'&tid='+tid+'&s_sourceinfo='+sourceinfo+'">'+val+'</a>'
+                        } else {
+                            tmp = '<a style="display: inline-block;cursor:pointer;font-size:16px;color: #428bca" target="_blank" href="/front/user/check/detail/?pid='+pid+'&did='+row._id+'&tid='+tid+'&s_sourceinfo='+sourceinfo+'">'+val+'</a>'
+                        }
+                        return tmp
+                    }},
+                {"data": "s_login", "defaultContent": ""},
+            ],
+            "initComplete": function () {
+                $("#dataTable_filter").append($('#status-div'))
+            },
+            "fnServerParams": function (e) {
+                e.s_status = $("#statusSelect option:selected").val()
+                e.s_excp = $("#dataSelect option:selected").val()
+            }
+        });
+
+        $('#statusSelect').on('changed.bs.select', function () {
+            ttable.api().ajax.reload();
+        })
+        $('#dataSelect').on('changed.bs.select', function () {
+            ttable.api().ajax.reload();
+        })
+    });
+
+    function checkResult() {
+        let num = {{ .T.taskCheckNum }}
+        if (num > 0) {
+            window.location.href = "/front/user/check/result?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype={{.T.stype}}&datatype={{.T.datatype}}"
+        }else {
+            showTip("没有审核数据")
+        }
+    }
+    function checkExcpResult() {
+        window.location.href = "/front/check/excp/result?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype={{.T.stype}}&datatype={{.T.datatype}}"
+    }
+</script>

+ 5 - 5
src/web/templates/project/project_clear.html

@@ -495,7 +495,7 @@
             let num0 = {{ .T.allIsTagDataNum }}     // 已标注
             if (num0 > 0) {
                 sessionStorage.setItem("check", "project")
-                window.location.href = "/front/user/check/data?pid="+projectid+"&s_sourceinfo={{.T.s_sourceinfo}}"+"&stype="+stype
+                window.location.href = "/front/jy/check/data?pid="+projectid+"&s_sourceinfo={{.T.s_sourceinfo}}"+"&stype="+stype
             }else {
                 showTip("没有质检数据")
             }
@@ -508,7 +508,7 @@
                 if (num1 > 0) {
                     if (num3 > 0) {
                         sessionStorage.setItem("check", "project")
-                        window.location.href = "/front/user/check/data?pid="+projectid+"&s_sourceinfo={{.T.s_sourceinfo}}"+"&stype="+stype+"&datatype=2"
+                        window.location.href = "/front/jy/check/data?pid="+projectid+"&s_sourceinfo={{.T.s_sourceinfo}}"+"&stype="+stype+"&datatype=2"
                     }else {
                         showTip("没有质检数据")
                     }
@@ -523,7 +523,7 @@
                                 hideLoading()
                                 if (r.success) {
                                     sessionStorage.setItem("check", "project")
-                                    window.location.href = "/front/user/check/data?pid="+projectid+"&s_sourceinfo={{.T.s_sourceinfo}}"+"&stype="+stype+"&datatype=1"
+                                    window.location.href = "/front/jy/check/data?pid="+projectid+"&s_sourceinfo={{.T.s_sourceinfo}}"+"&stype="+stype+"&datatype=1"
                                 } else {
                                     showTip(r.msg);
                                 }
@@ -541,7 +541,7 @@
             let num0 = {{ .T.IsNotOkIsTagDataNum }}
             if (num0 > 0) {
                 sessionStorage.setItem("check", "project")
-                window.location.href = "/front/user/check/data?pid="+projectid+"&s_sourceinfo={{.T.s_sourceinfo}}"+"&stype="+stype
+                window.location.href = "/front/jy/check/data?pid="+projectid+"&s_sourceinfo={{.T.s_sourceinfo}}"+"&stype="+stype
             }else {
                 showTip("没有质检数据")
             }
@@ -595,6 +595,6 @@
     }
     function checkMethod1(pid, tid, sourceinfo) {
         sessionStorage.setItem("check", "project")
-        window.location.href = "/front/user/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=group"
+        window.location.href = "/front/jy/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=group"
     }
 </script>

+ 228 - 25
src/web/templates/project/project_list.html

@@ -207,6 +207,12 @@
                                         <input type="text" class="form-control" id="edit-person">
                                     </div>
                                 </div>
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label">数据类型</label>
+                                    <div class="col-sm-5">
+                                        <select class="form-control selectpicker" id="dataTypeSelect" title="请选择"></select>
+                                    </div>
+                                </div>
                                 <div class="form-group">
                                     <label class="col-sm-3 control-label">选择标注字段</label>
                                     <div class="col-sm-5">
@@ -227,6 +233,96 @@
     </div><!-- /.modal -->
 </div>
 
+<div class="modal fade" id="modal-add_data" tabindex="-1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog" style="width: 50%">
+        <div class="modal-content">
+            <div class="modal-header">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+                    <div class="edit-info">
+                        <span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
+                        <span class="h4">项目新增数据</span>
+                    </div>
+                    <div class="edit-form">
+                        <hr>
+                        <div class="form-group">
+                            <label class="radio-inline">
+                                <input type="radio" name="stype-add" value="coll" checked>数据库导入
+                            </label>
+                            <label class="radio-inline">
+                                <input type="radio" name="stype-add" value="excel">Excel表导入
+                            </label>
+                        </div>
+                        <form id="model-form-data" class="form-horizontal" enctype="multipart/form-data">
+                            <div class="box-body">
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label">项目名称</label>
+                                    <div class="col-sm-5">
+                                        <input type="text" class="form-control" id="project-name-add" placeholder="项目名称" readonly>
+                                    </div>
+                                </div>
+                                <div id="import-coll-add">
+                                    <h5><i class="glyphicon glyphicon-bookmark"
+                                           style="color: #00c4ff;margin-right: 6px"></i>数据来源</h5>
+                                    <div class="form-group">
+                                        <label class="col-sm-3 control-label">数据库名</label>
+                                        <div class="col-sm-5">
+                                            <input type="text" class="form-control" id="db-name-add" value="jyqyfw"
+                                                   readonly>
+                                        </div>
+                                    </div>
+                                    <div class="form-group">
+                                        <label class="col-sm-3 control-label">数据表名</label>
+                                        <div class="col-sm-5">
+                                            <input type="text" class="form-control" id="coll-name-add"
+                                                   value="usermail_history" readonly>
+                                        </div>
+                                    </div>
+                                    <div class="form-group">
+                                        <label class="col-sm-3 control-label">数据导出ID</label>
+                                        <div class="col-sm-5">
+                                            <input type="text" class="form-control" id="data-id-add" placeholder="数据导出ID">
+                                        </div>
+                                    </div>
+                                </div>
+
+                                <div id="import-excel-add" style="display: none">
+                                    <h5><i class="glyphicon glyphicon-bookmark"
+                                           style="color: #00c4ff;margin-right: 6px"></i>数据信息</h5>
+                                    <div class="form-group">
+                                        <label class="col-sm-3 control-label">选择文件</label>
+                                        <div class="col-sm-5">
+                                            <input type="file" name="file" id="uploadfile-add">
+                                        </div>
+                                    </div>
+                                </div>
+                                <h5><i class="glyphicon glyphicon-bookmark"
+                                       style="color: #00c4ff;margin-right: 6px"></i>数据存储</h5>
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label"><span style="color:red;">* </span>数据库名</label>
+                                    <div class="col-sm-5">
+                                        <input type="text" class="form-control" value="jyqykhfw" readonly>
+                                    </div>
+                                </div>
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label"><span style="color:red;">* </span>数据表名</label>
+                                    <div class="col-sm-5">
+                                        <input type="text" class="form-control" id="coll-save-name-add" placeholder="数据表名" readonly>
+                                    </div>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <input type="button" onclick="importAddData()" class="btn btn-primary" value="导入">
+                <input type="button" onclick="cancelModel()" class="btn btn-default" value="取消">
+            </div>
+        </div>
+    </div><!-- /.modal -->
+</div>
+
 <div class="modal fade" id="loadingModal" backdrop="static" keyboard="false">
     <div style="width: 250px;height:100px; z-index: 20000; position: absolute; text-align: center; left: 50%; top: 50%;margin-left:-100px;margin-top:-10px">
         <div id="loadText" class="progress progress-striped active"
@@ -242,21 +338,11 @@
 
     let stype = "coll";
     let fields = {{ .T.fields }}
+    let dataTypeArr = {{ .T.dataTypeArr }}
+    let dataTypeMap = {{ .T.dataTypeMap }}
     let projectmap = {}
     let existName = false
 
-    //展示loading框
-    showLoading = function (text){
-        if(text){
-            $("#loadText").html(text)
-        }
-        $('#loadingModal').modal({backdrop: 'static', keyboard: false});
-    }
-    //隐藏掉loading框
-    hideLoading = function (){
-        $('#loadingModal').modal('hide');
-    }
-
     $(function () {
         ttable = $('#dataTable').dataTable({
             "paging": true,
@@ -320,21 +406,24 @@
                         if (row.b_isassessment) {
                             tmp = '<div>' +
                                 '<a class="btn btn-sm btn-primary" onclick="editPro(\'' + pos.row + '\')">编辑</a>&nbsp;&nbsp;' +
+                                '<a class="btn btn-sm btn-primary" onclick="addData(\'' + pos.row + '\')">新增</a>&nbsp;&nbsp;' +
                                 '<a class="btn btn-sm btn-primary" onclick="clearPro(\''+ pos.row +'\')">查看</a>&nbsp;&nbsp;' +
                                 '<a class="btn btn-sm btn-primary" onclick="checkMethod(\'' + val + '\',\''+row.s_sourceinfo+'\',\'' + row.s_status + '\')">质检</a>&nbsp;&nbsp;' +
+                                '<br>' +
                                 // '<a class="btn btn-sm btn-primary" href="">质检结果</a>&nbsp;&nbsp;' +
-                                '<a class="btn btn-sm btn-primary" onclick="completePro(\'' + val + '\',\''+row.s_sourceinfo+'\',\'' + row.s_status + '\')">完成</a>&nbsp;&nbsp;' +
+                                '<a class="btn btn-sm btn-primary" style="margin-top: 5px" onclick="completePro(\'' + val + '\',\''+row.s_sourceinfo+'\',\'' + row.s_status + '\')">完成</a>&nbsp;&nbsp;' +
                                 '</div>';
                         }else {
                             tmp = '<div>' +
                                 '<a class="btn btn-sm btn-primary" onclick="editPro(\'' + pos.row + '\')">编辑</a>&nbsp;&nbsp;' +
+                                '<a class="btn btn-sm btn-primary" onclick="addData(\'' + pos.row + '\')">新增</a>&nbsp;&nbsp;' +
                                 '<a class="btn btn-sm btn-primary" onclick="clearPro(\''+ pos.row +'\')">清洗</a>&nbsp;&nbsp;' +
                                 '<a class="btn btn-sm btn-primary" onclick="checkMethod(\'' + val + '\',\''+row.s_sourceinfo+'\',\'' + row.s_status + '\')">质检</a>&nbsp;&nbsp;' +
+                                '<br>' +
                                 // '<a class="btn btn-sm btn-primary" href="">质检结果</a>&nbsp;&nbsp;' +
-                                '<a class="btn btn-sm btn-primary" onclick="completePro(\'' + val + '\',\''+row.s_sourceinfo+'\',\'' + row.s_status + '\')">完成</a>&nbsp;&nbsp;' +
+                                '<a class="btn btn-sm btn-primary" style="margin-top: 5px" onclick="completePro(\'' + val + '\',\''+row.s_sourceinfo+'\',\'' + row.s_status + '\')">完成</a>&nbsp;&nbsp;' +
                                 '</div>';
                         }
-
                         return tmp
                     }
                 }
@@ -369,7 +458,25 @@
                 $("#import-excel").attr("style", "display:block;")
             }
         });
+        $('input[type=radio][name=stype-add]').change(function () {
+            if (this.value === 'coll') {
+                stype = "coll"
+                $("#import-coll-add").attr("style", "display:block;")
+                $("#import-excel-add").attr("style", "display:none;")
+            } else if (this.value === 'excel') {
+                stype = "excel"
+                $("#import-coll-add").attr("style", "display:none;")
+                $("#import-excel-add").attr("style", "display:block;")
+            }
+        });
 
+        for (let i in dataTypeArr) {
+            let opt = document.createElement('option');
+            opt.innerText = dataTypeArr[i];
+            opt.value = dataTypeArr[i];
+            $('#dataTypeSelect')[0].appendChild(opt)
+        }
+        $("#dataTypeSelect").selectpicker("refresh");
         for (let i in fields) {
             let opt = document.createElement('option');
             opt.innerText = fields[i]["s_name"];
@@ -404,6 +511,7 @@
     function cancelModel() {
         $("#modal-create-project").modal('hide')
         $("#modal-edit-project").modal('hide')
+        $("#modal-add_data").modal('hide')
     }
 
     function importData() {
@@ -491,17 +599,16 @@
 
     function editPro(index) {
         projectmap = ttable.fnGetData()[index]
-        console.log(projectmap.v_fields)
         $('#modal-edit-project').modal('show')
         $('#company-edit-name').val(projectmap["s_entname"])
         $('#rule-edit-name').val(projectmap["s_rulename"])
         $('#dpart-edit-name').val(projectmap["s_departname"])
         $('#edit-person').val(projectmap["s_personname"])
         $("#markFieldSelect").selectpicker("deselectAll");
-        if (projectmap.v_fields !== undefined) {
+        if (projectmap.v_fields_diy !== undefined) {
             $('#markFieldSelect option').each(function(){
                 let v = $(this).val()
-                if (projectmap.v_fields[v] !== undefined) {
+                if (projectmap.v_fields_diy[v] !== undefined) {
                     $(this)[0].selected = true
                 }
             })
@@ -509,6 +616,17 @@
         }else {
             $("#markFieldSelect").selectpicker("deselectAll");
         }
+        if (projectmap.s_datatype !== undefined) {
+            $('#dataTypeSelect option').each(function(){
+                let v = $(this).val()
+                if (projectmap.s_datatype === v) {
+                    $(this)[0].selected = true
+                }
+            })
+            $("#dataTypeSelect").selectpicker("refresh");
+        }else {
+            $("#dataTypeSelect").selectpicker("deselectAll");
+        }
     }
 
     function saveData() {
@@ -519,16 +637,30 @@
         tmp["s_rulename"] = $('#rule-edit-name').val()
         tmp["s_personname"] = $('#edit-person').val()
 
+        let type = $('#dataTypeSelect').val();
+        if (type === "") {
+            showTip("请选择数据类型")
+            return
+        }
+        tmp["s_datatype"] = type
         let fieldArr = $('#markFieldSelect').val();
         let m = {}
-        if (fieldArr.length > 0) {
-            for (const i in fields) {
-                if (fieldArr.indexOf(fields[i]["s_code"]) > -1) {
-                    m[fields[i]["s_code"]] = fields[i]["s_name"]
+        let m1 = {}
+        let arr = dataTypeMap[type]
+        for (const i in fields) {
+            if (fieldArr.indexOf(fields[i]["s_code"]) > -1) {
+                m[fields[i]["s_code"]] = fields[i]["s_name"]
+                m1[fields[i]["s_code"]] = fields[i]["s_name"]
+            }else {
+                if (arr.indexOf(fields[i]["s_code"]) > -1) {
+                    m1[fields[i]["s_code"]] = fields[i]["s_name"]
                 }
             }
         }
-        tmp["v_fields"] = JSON.stringify(m)
+        console.log(m)
+        console.log(m1)
+        tmp["v_fields_diy"] = JSON.stringify(m)
+        tmp["v_fields"] = JSON.stringify(m1)
         if (s1 === JSON.stringify(tmp)) {
             showTip("未做修改");
         } else {
@@ -536,7 +668,8 @@
                 url: "/front/project/save",
                 type: 'POST',
                 data: {"s_type": stype, "s_departname": tmp["s_departname"], "s_personname": tmp["s_personname"],
-                    "s_rulename": tmp["s_rulename"], "v_fields": tmp["v_fields"], "s_name": tmp["s_name"]},
+                    "s_rulename": tmp["s_rulename"], "v_fields_diy": tmp["v_fields_diy"], "s_name": tmp["s_name"],
+                    "v_fields": tmp["v_fields"], "s_datatype": type},
                 success: function (r) {
                     if (r.success) {
                         showTip("保存成功", 500)
@@ -602,7 +735,7 @@
                 success: function (r) {
                     if (r.success) {
                         sessionStorage.setItem("check", "project")
-                        window.location.href = "/front/user/check/data?pid=" + pid + "&s_sourceinfo=" + sourceinfo
+                        window.location.href = "/front/jy/check/data?pid=" + pid + "&s_sourceinfo=" + sourceinfo
                     }else {
                         showTip(r.msg);
                     }
@@ -636,4 +769,74 @@
             })
         }
     }
+
+    function addData(index) {
+        projectmap = ttable.fnGetData()[index]
+        if (status !== "已完成") {
+            stype = "coll"
+            $("#project-name-add").val(projectmap["s_name"])
+            $("#coll-save-name-add").val(projectmap["s_sourceinfo"])
+            $("#modal-add_data").modal('show')
+        }else {
+            showTip("项目已完成,无法添加新的数据")
+        }
+    }
+
+    function importAddData() {
+        let projectid = projectmap["_id"]
+        if (stype === "coll") {
+            let dataid = $('#data-id-add').val()
+            if (dataid === "") {
+                alert("数据导出ID为必填项")
+                return;
+            }
+            showLoading("正在加载数据,请稍候...")
+            $.ajax({
+                url: "/front/project/new/data",
+                type: 'POST',
+                data: {"projectid": projectid, "s_historyid": dataid, "s_type": stype},
+                success: function (r) {
+                    hideLoading()
+                    if (r.success) {
+                        $("#modal-add_data").modal('hide')
+                        let msg = r.msg + "<br>"+"导入数据:"+r.importnum+"条;成功:"+r.successnum+"条;失败:"+r.failnum+"条。"
+                        showMsg(msg, 1500);
+                        ttable.api().ajax.reload();
+                    } else {
+                        showMsg(r.msg, 2000)
+                    }
+                }
+            })
+        }else if (stype === "excel") {
+            let formData = new FormData();
+            formData.append("projectid", projectid)
+            formData.append("s_type", stype)
+            let file = $('#uploadfile-add')[0].files[0]
+            if (file) {
+                formData.append("xlsx", file)
+                showLoading("正在加载数据,请稍候...")
+                $.ajax({
+                    url: "/front/project/new/data",
+                    type: 'POST',
+                    data: formData,
+                    cache: false,
+                    processData: false,
+                    contentType: false,
+                    success: function (r) {
+                        hideLoading()
+                        if (r.success) {
+                            $("#modal-add_data").modal('hide')
+                            let msg = r.msg + "<br>"+"导入数据:"+r.importnum+"条;成功:"+r.successnum+"条;失败:"+r.failnum+"条。"
+                            showMsg(msg, 1500);
+                            ttable.api().ajax.reload();
+                        } else {
+                            showMsg(r.msg, 2000);
+                        }
+                    }
+                })
+            } else {
+                showTip("请选择上传文件");
+            }
+        }
+    }
 </script>

+ 61 - 6
src/web/templates/project/remark_detail.html

@@ -533,6 +533,7 @@
     //基本信息
     var common = {{ .T.common }}
     var uInput = [];
+    let k;
     for (k in common) {
         var tmp = {}
         tmp.title = common[k].descript
@@ -594,6 +595,7 @@
     var c_worder = {{ .T.worder }}
     var worder_new = {{ .T.worder_new }}
     var c_content = [];
+    let i;
     for (k in c_worder) {
         var c_uInput = [];
         for (i in c_worder[k]) {
@@ -626,11 +628,6 @@
             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=['是','否']
-            //}
             c_uInput[i] = tmp
         }
         var content = {};
@@ -642,6 +639,29 @@
         content.content = []
         pcl_content[k] = content
     }
+    //采购意向
+    var purchasinglist_1 = {{ .T.purchasinglist_1 }}
+    var pcl_new_1 = {{ .T.pcl_new_1 }}
+    var pcl_content_1 = [];
+    for (k in purchasinglist_1) {
+        let c_uInput = [];
+        for (i in purchasinglist_1[k]) {
+            let tmp = {}
+            tmp.title = purchasinglist_1[k][i].descript
+            tmp.input = purchasinglist_1[k][i].value
+            tmp.key = purchasinglist_1[k][i].key
+            tmp.status = purchasinglist_1[k][i].status
+            c_uInput[i] = tmp
+        }
+        let content = {};
+        content.title = "标的物"
+        content.show = true
+        content.status = pcl_new_1[k]["status"]
+        content.uInput = c_uInput
+        content.isnew = pcl_new_1[k]["isnew"] || false
+        content.content = []
+        pcl_content_1[k] = content
+    }
 
     //var ispackage='{{.T.ispackage}}'
     //子包信息
@@ -709,7 +729,23 @@
             pclfInput.push(tempNode)
         }
     }
-
+    var pclf1 = {{ .T.PurchasinglistField1 }}
+    const pclfInput1 = [];
+    for (i in pclf1) {
+        for (key in pclf1[i]) {
+            const tempNode = {
+                input: "",
+                key: key,
+                status: "2",
+                title: pclf1[i][key]
+            };
+            //if(key== "pclisover"){
+            //  tempNode.select= '是'
+            //  tempNode.selectArr=['是','否']
+            //}
+            pclfInput1.push(tempNode)
+        }
+    }
 
     var wodf = {{ .T.WinnerorderField }}
     var wodfInput = []
@@ -790,6 +826,14 @@
                 status: purchasing_status,
                 content: pcl_content
                 }, {
+                title: '采购意向信息',
+                show:false,
+                showCheck: true,
+                key: 'purchasinglist_1',
+                // checkType: {{.T.ck_pkgisext}},
+                status: purchasing_status,
+                content: pcl_content_1
+                }, {
                 title: '多包信息',
                 show:false,
                 showCheck: true,
@@ -1101,6 +1145,17 @@
                             }
                             break
                         }
+                        case "采购意向信息": {
+                            tempNode = {
+                                //content: [],
+                                show: true,
+                                isnew: true,
+                                status: "2",
+                                title: "标的物",
+                                uInput: JSON.parse(JSON.stringify(pclfInput1))
+                            }
+                            break
+                        }
                         case "多包信息": {
                             tempNode = {
                                 //content: [],

+ 2 - 12
src/web/templates/project/remark_jy_list.html

@@ -33,17 +33,8 @@
                                 <input type="number" id="maxInput" class="form-control" style="width: 70px;padding: 5px" placeholder="最大值">
                             </label>
                             <label id="fieldStatus1" class="form-inline" style="display: none;padding-left: 10px">
-<!--                                <select class="form-control selectpicker" id="fieldExist">-->
-<!--                                    <option value="0">存在</option>-->
-<!--                                    <option value="-1">不存在</option>-->
-<!--                                </select></label>-->
                                 <input type="checkbox" id="field-exist"> 不存在</label>
                             <label class="form-inline" id="fieldStatus2" style="display: none;padding-left: 10px">
-<!--                                <select class="form-control selectpicker" id="statusSelect">-->
-<!--                                    <option value=-1>全部</option>-->
-<!--                                    <option value=0>未标注</option>-->
-<!--                                    <option value=1>已标注</option>-->
-<!--                                </select></label>-->
                                 <input type="checkbox" id="field-tag"> 未标注</label>
                             <label class="form-inline" id="search-btn" style="padding-left: 10px;display: none">
                                 <input type="button" class="btn btn-sm btn-default" value="搜索" onclick="searchBtn()">
@@ -72,7 +63,7 @@
 
 {{include "com/footer.html"}}
 <script>
-    menuActive("/front/user/task/list");
+    menuActive("project");
 
     let pid = {{ .T.pid }}
     let stype = {{ .T.stype }}
@@ -92,7 +83,7 @@
             "autoWidth": false,
             "serverSide": true,
             "ajax": {
-                "url": "",
+                "url": "/front/user/jymark/list",
                 "type": "post",
                 "data": {"pid": pid, "s_sourceinfo": sourceinfo, "stype": stype}
             },
@@ -174,7 +165,6 @@
         $('#fieldSelect').on('changed.bs.select', function () {
             // ttable.api().ajax.reload();
             let v = $("#fieldSelect option:selected").val()
-            console.log(v, v !== "-1")
             if (v !== "-1") {
                 $('#fieldStatus1').show()
                 $('#fieldStatus2').show()

+ 0 - 2
src/web/templates/project/task_detail.html

@@ -467,8 +467,6 @@
         }
     }
     function checkMethod(pid, tid, sourceinfo) {
-        sessionStorage.setItem("check", "detail")
         window.location.href = "/front/user/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo
-
     }
 </script>

+ 1 - 1
src/web/templates/project/task_group_list.html

@@ -160,6 +160,6 @@
 
     function checkMethod(pid, tid, sourceinfo) {
         sessionStorage.setItem("check", "group")
-        window.location.href = "/front/user/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=group"
+        window.location.href = "/front/jy/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=group"
     }
 </script>

+ 1 - 1
src/web/templates/project/task_list.html

@@ -288,6 +288,6 @@
 
     function checkMethod(pid, tid, sourceinfo) {
         sessionStorage.setItem("check", "jygroup")
-        window.location.href = "/front/user/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=group"
+        window.location.href = "/front/jy/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=group"
     }
 </script>