فهرست منبع

Merge branch 'dev2.0' of http://192.168.3.207:8080/data_processing/data_validation into dev2.0

* 'dev2.0' of http://192.168.3.207:8080/data_processing/data_validation:
  xg
  xg
  xg
  xg

# Conflicts:
#	src/front/front.go
Jianghan 3 سال پیش
والد
کامیت
95c36c8f49

+ 5 - 2
src/front/front.go

@@ -81,12 +81,15 @@ type Front struct {
 	groupUserTaskList    xweb.Mapper `xweb:"/front/group/user/task/list"`  //用户组下用户任务列表
 
 	//mark
+	dataMark     xweb.Mapper `xweb:"/front/data/mark"` //数据标注
 	remarkList   xweb.Mapper `xweb:"/front/user/remark/list"`
+	jyMarkList   xweb.Mapper `xweb:"/front/user/jymark/list"` //剑鱼用户查看标注数据列表
 	remarkDetail xweb.Mapper `xweb:"/front/user/remark/detail"`
-	dataMark     xweb.Mapper `xweb:"/front/data/mark"` //数据标注
 
 	//check
-	checkList xweb.Mapper `xweb:"/front/user/check/list"`
+	checkList   xweb.Mapper `xweb:"/front/user/check/list"`
+	checkData   xweb.Mapper `xweb:"/front/user/check/data"`
+	checkDetail xweb.Mapper `xweb:"/front/user/check/detail"`
 }
 
 func (f *Front) Index() {

+ 2 - 3
src/front/group.go

@@ -15,16 +15,15 @@ import (
 // GroupTaskListByGroup 用户组权限用户组任务列表
 func (f *Front) GroupTaskListByGroup() {
 	defer qu.Catch()
-	user := f.GetSession("user").(map[string]interface{})
-	role := qu.ObjToString(user["i_role"]) //当前登录用户
 	if f.Method() == "POST" {
+		user := f.GetSession("user").(map[string]interface{})
+		role := qu.ObjToString(user["i_role"])
 		start, _ := f.GetInteger("start")
 		limit, _ := f.GetInteger("length")
 		draw, _ := f.GetInteger("draw")
 		status := f.GetString("s_status")
 		searchStr := f.GetString("search[value]")
 		search := strings.TrimSpace(searchStr)
-		user := f.GetSession("user").(map[string]interface{})
 		groupId := qu.ObjToString(user["s_groupid"])
 		query := map[string]interface{}{
 			"s_stype": "group", //检索用户组任务

+ 100 - 18
src/front/mark.go

@@ -10,6 +10,92 @@ import (
 	"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") //数据源表
+		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{}{}
+		qu.Debug(stype, dataType)
+		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 {
+				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
+		}
+		qu.Debug("query:", query)
+		list, _ := util.Mgo.Find(sourceInfo, query, map[string]interface{}{"_id": 1}, nil, false, start, limit)
+		count := util.Mgo.Count(sourceInfo, query)
+		//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)
+	}
+}
+
 // DataMark 数据标注
 func (f *Front) DataMark() {
 	qu.Debug("------------------")
@@ -66,7 +152,6 @@ func (f *Front) DataMark() {
 				continue
 			}
 			istag, _ := val["checkAllTag"].(bool)
-			qu.Debug(istag)
 			if j == 0 { //基本信息
 				MarkBase(content, tagSet, baseSet, baseUnset)
 			} else if j == 1 { //时间地点
@@ -83,18 +168,6 @@ func (f *Front) DataMark() {
 		}
 	}
 	//
-	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)
-	//
 	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": "查询用户任务失败"})
@@ -106,9 +179,6 @@ func (f *Front) DataMark() {
 	baseInfo, _ := (*dataInfo)["v_baseinfo"].(map[string]interface{})
 	if tagInfo != nil && len(tagInfo) > 0 {
 		for field, tmpStatus := range tagSet { //比对本次标注信息和历史标注信息
-			if field == "purchasinglist_alltag" {
-				continue
-			}
 			status := qu.IntAll(tmpStatus)            //此次被标注字段的状态
 			markedStatus := qu.IntAll(tagInfo[field]) //历史标注状态
 			if status == 1 && markedStatus != 0 {     //此次标注结果为正确,且有历史标注记录,不做修改
@@ -122,8 +192,20 @@ func (f *Front) DataMark() {
 			//}
 		}
 	}
+	//
+	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 {
+	if len(tagSet) > 0 || baseInfo["purchasinglist_alltag"] != nil { //purchasinglist_alltag特殊处理
 		//1、更新数据源信息
 		setResult := map[string]interface{}{ //更新字段集
 			"i_updatetime": time.Now().Unix(),
@@ -514,7 +596,7 @@ func SaveLog(s_infoid, s_usertaskid, username, userid, s_stype string, baseInfo,
 	defer qu.Debug()
 	v_before := map[string]interface{}{}
 	for f, v := range allTagFields {
-		if _, ok := v.(bool); ok { //表示此次标注status=1的字段
+		if _, ok := v.(bool); ok && f != "purchasinglist_alltag" { //表示此次标注status=1的字段
 			allTagFields[f] = baseInfo[f]
 		}
 		v_before[f] = baseInfo[f]

+ 3 - 0
src/front/quality.go

@@ -114,6 +114,9 @@ func calculateFieldScore(tmp map[string]interface{}, field_tag []string) map[str
 			"b_istagging":   b_istagging,
 			"b_isprchasing": b_isprchasing,
 			"i_ckdata":      ckdata,
+			"b_istag":       true,
+			"b_isgivegroup": true,
+			"b_isgiveuser":  true,
 		},
 	}
 }

+ 90 - 7
src/front/remark.go

@@ -537,10 +537,10 @@ func GetNextDataId(id, coll string) string {
 
 func (f *Front) CheckList() {
 	qu.Catch()
-	user := f.GetSession("user").(map[string]interface{})
-	s_role := qu.ObjToString(user["i_role"])
-	s_personid := qu.ObjToString(user["id"])
 	if f.Method() == "POST" {
+		user := f.GetSession("user").(map[string]interface{})
+		iRole := qu.ObjToString(user["i_role"])
+		gid := qu.ObjToString(user["s_groupid"])
 		start, _ := f.GetInteger("start")
 		limit, _ := f.GetInteger("length")
 		draw, _ := f.GetInteger("draw")
@@ -548,10 +548,10 @@ func (f *Front) CheckList() {
 		searchStr := f.GetString("search[value]")
 		search := strings.TrimSpace(searchStr)
 		query := map[string]interface{}{
-			"s_stype": "user",
+			"s_stype": "group",
 		}
-		if s_role != "0" && s_role != "1" {
-			query["s_personid"] = s_personid
+		if iRole != "0" {
+			query["s_groupid"] = gid
 		}
 		if status != "-1" { //任务状态
 			query["s_status"] = status
@@ -577,6 +577,89 @@ func (f *Front) CheckList() {
 		}
 		f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
 	} else {
-		_ = f.Render("project/check_list.html")
+		_ = f.Render("project/check_task_list.html")
 	}
 }
+
+func (f *Front) CheckData() {
+	qu.Catch()
+	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")
+		searchStr := f.GetString("search[value]")
+		search := strings.TrimSpace(searchStr)
+		query := map[string]interface{}{
+			"s_grouptaskid": tid,
+			"b_istag":       true,
+		}
+		if search != "" {
+			query["$or"] = []interface{}{
+				map[string]interface{}{"v_baseinfo.title": map[string]interface{}{"$regex": search}},
+			}
+		}
+		qu.Debug("Query:", query)
+		field := map[string]interface{}{"title": 1, "v_baseinfo": 1, "b_istag": 1, "i_ckdata": 1, "s_login": 1}
+		info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, field, false, start, limit)
+		count := util.Mgo.Count(sourceinfo, query)
+		qu.Debug(query, sourceinfo, count)
+		f.ServeJson(map[string]interface{}{
+			"draw":            draw,
+			"data":            *info,
+			"recordsFiltered": count,
+			"recordsTotal":    count,
+		})
+	} else {
+		f.T["tid"] = tid
+		f.T["sourceinfo"] = sourceinfo
+		_ = f.Render("project/check_data_list.html", &f.T)
+	}
+}
+
+func (f *Front) CheckDetail() {
+	qu.Catch()
+	tid := f.GetString("tid")
+	pid := f.GetString("pid")
+	did := f.GetString("did")
+	coll := f.GetString("s_sourceinfo")
+	project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, `{"v_fields": 1}`)
+	if len(*project) > 0 {
+		field := make(map[string]bool)
+		vf := (*project)["v_fields"].(map[string]interface{})
+		for k := range vf {
+			field[k] = true
+		}
+		f.T["fields"] = field
+	}
+	qu.Debug(pid, did, coll)
+	rep := getDetail(did, coll)         //获取本条公告的信息
+	f.T["otherInfo"] = rep["otherInfo"] //展示关联公告信息
+	f.T["moreInfo"] = rep["moreInfo"]   //更多关联公告信息
+	f.T["pid"] = pid
+	f.T["tid"] = tid
+	f.T["did"] = did
+	f.T["coll"] = coll
+	f.T["info"] = rep["info"]
+	f.T["common"] = rep["common"]
+	f.T["worder"] = rep["worder"]
+	f.T["packs"] = rep["packs"]
+	f.T["packskey"] = rep["packskey"]
+	f.T["ck_pclistag"] = rep["purchasingTag"]
+	f.T["timeplace"] = rep["timeplace"]
+	f.T["purchasinglist"] = rep["purchasinglist"]
+	f.T["other"] = rep["other"]
+	f.T["PurchasinglistField"] = util.PurchasinglistField
+	f.T["WinnerorderField"] = util.WinnerorderField
+	f.T["PackageField"] = util.PackageField
+	f.T["topsubtype"] = util.TopSubStypeArr2
+	f.T["ck_purchasinglist"] = rep["ck_purchasinglist"]
+	f.T["ck_package"] = rep["ck_package"]
+	f.T["ck_winnerorder"] = rep["ck_winnerorder"]
+	f.T["worder_new"] = rep["worder_new"]
+	f.T["pcl_new"] = rep["pcl_new"]
+	f.T["pkg_new"] = rep["pkg_new"]
+	f.T["nextid"] = GetNextDataId(did, coll) //下一条id
+	_ = f.Render("project/check_detail.html", &f.T)
+}

+ 5 - 5
src/front/user.go

@@ -505,8 +505,8 @@ func (f *Front) UserTaskList() {
 				map[string]interface{}{"s_projectname": map[string]interface{}{"$regex": search}},
 			}
 		}
-		qu.Debug("Query:", query)
 		count := Mgo.Count(TASKCOLLNAME, query)
+		qu.Debug("Query:", query, count)
 		list, _ := Mgo.Find(TASKCOLLNAME, query, map[string]interface{}{"_id": -1}, nil, false, start, limit)
 		for _, l := range *list {
 			if status := qu.ObjToString(l["s_status"]); status == "进行中" { //更新任务进度
@@ -545,15 +545,15 @@ func (f *Front) UserTaskRetrieve() {
 // UserTaskDeliver 标注完成交付任务
 func (f *Front) UserTaskDeliver() {
 	defer qu.Catch()
-	success := true
+	success := false
 	msg := ""
 	user := f.GetSession("user").(map[string]interface{})
 	username := qu.ObjToString(user["s_login"])
-	userTaskId := f.GetString("taskid") //用户任务id
-	qu.Debug("User Task Id:", userTaskId)
+	userTaskId := f.GetString("taskid")                                                                  //用户任务id
 	sourceInfo := f.GetString("s_sourceinfo")                                                            //数据源表
 	count := Mgo.Count(sourceInfo, map[string]interface{}{"s_usertaskid": userTaskId, "b_istag": false}) //查询是否含有未标注数据
-	if count == 0 {                                                                                      //标注完成更新任务状态
+	qu.Debug("User Task Id:", userTaskId, count)
+	if count == 0 { //标注完成更新任务状态
 		set := map[string]interface{}{
 			"s_status":       "已完成", //收回、关闭时默认任务状态已完成
 			"i_updatetime":   time.Now().Unix(),

+ 43 - 27
src/util/config.go

@@ -4,6 +4,7 @@ import (
 	"mongodb"
 	qu "qfw/util"
 	"qfw/util/elastic"
+	"sort"
 	"sync"
 )
 
@@ -36,6 +37,7 @@ var (
 	PurchasinglistField []map[string]string
 	PackageField        []map[string]string
 	WinnerorderField    []map[string]string
+	AllFieldArr         []map[string]string
 	TopSubStypeArr      []string
 	TopSubStypeArr2     []string
 )
@@ -57,6 +59,7 @@ const BIDDINGSTARTID = "5a862f0640d2d9bbe88e3cec"
 const PROJECTCOLLNAME = "f_project"
 const TASKCOLLNAME = "f_task"
 const LOGCOLLNAME = "l_taglog"
+const SPECIALTYPE = "二级不存在"
 
 func InitConfig() {
 	Mgo = &mongodb.MongodbSim{
@@ -124,33 +127,46 @@ func InitConfig() {
 	}
 
 	BiaoZhu = Sysconfig["biaozhu"].(map[string]interface{})
-	//common := BiaoZhu["common"].([]interface{})
-	//timeplace := BiaoZhu["timeplace"].([]interface{})
-	//other := BiaoZhu["other"].([]interface{})
-	//for _, com := range common {
-	//	tmp := com.(map[string]interface{})
-	//	key := qu.ObjToString(tmp["key"])
-	//	if key == "" {
-	//		continue
-	//	}
-	//descript := qu.ObjToString(tmp["descript"])
-	//tmpAllField = append(tmpAllField, descript)
-	//AllFieldMap[descript] = key
-	//}
-	//for _, tp := range timeplace {
-	//tmp := tp.(map[string]interface{})
-	//key := qu.ObjToString(tmp["key"])
-	//descript := qu.ObjToString(tmp["descript"])
-	//tmpAllField = append(tmpAllField, descript)
-	//AllFieldMap[descript] = key
-	//}
-	//for _, o := range other {
-	//tmp := o.(map[string]interface{})
-	//key := qu.ObjToString(tmp["key"])
-	//descript := qu.ObjToString(tmp["descript"])
-	//tmpAllField = append(tmpAllField, descript)
-	//AllFieldMap[descript] = key
-	//}
+	tmpAllField := Arr{}
+	AllFieldMap := map[string]string{}
+	AllFieldArr = []map[string]string{}
+	common := BiaoZhu["common"].([]interface{})
+	timeplace := BiaoZhu["timeplace"].([]interface{})
+	other := BiaoZhu["other"].([]interface{})
+	for _, com := range common {
+		tmp := com.(map[string]interface{})
+		key := qu.ObjToString(tmp["key"])
+		if key == "" {
+			continue
+		}
+		descript := qu.ObjToString(tmp["descript"])
+		tmpAllField = append(tmpAllField, descript)
+		AllFieldMap[descript] = key
+	}
+	for _, tp := range timeplace {
+		tmp := tp.(map[string]interface{})
+		key := qu.ObjToString(tmp["key"])
+		descript := qu.ObjToString(tmp["descript"])
+		tmpAllField = append(tmpAllField, descript)
+		AllFieldMap[descript] = key
+	}
+	for _, o := range other {
+		tmp := o.(map[string]interface{})
+		key := qu.ObjToString(tmp["key"])
+		descript := qu.ObjToString(tmp["descript"])
+		tmpAllField = append(tmpAllField, descript)
+		AllFieldMap[descript] = key
+	}
+	tmpAllField = append(tmpAllField, "标的物列表")
+	tmpAllField = append(tmpAllField, "多包")
+	tmpAllField = append(tmpAllField, "中标候选人")
+	AllFieldMap["标的物列表"] = "purchasinglist"
+	AllFieldMap["多包"] = "package"
+	AllFieldMap["中标候选人"] = "winnerorder"
+	sort.Sort(tmpAllField)
+	for _, f := range tmpAllField {
+		AllFieldArr = append(AllFieldArr, map[string]string{AllFieldMap[f]: f})
+	}
 	PurchasinglistField = []map[string]string{}
 	pcls, _ := BiaoZhu["purchasinglist"].([]interface{})
 	for _, pcl := range pcls {

+ 39 - 0
src/util/sorthan.go

@@ -0,0 +1,39 @@
+package util
+
+import (
+	"bytes"
+	"io/ioutil"
+
+	"golang.org/x/text/encoding/simplifiedchinese"
+	"golang.org/x/text/transform"
+)
+
+type Arr []string
+
+func (a Arr) Len() int { return len(a) }
+func (a Arr) Less(i, j int) bool {
+	tmp1, _ := UTF82GBK(a[i])
+	tmp2, _ := UTF82GBK(a[j])
+	tmp2Len := len(tmp2)
+	for idx, chr := range tmp1 {
+		if idx > tmp2Len-1 {
+			return false
+		}
+		if chr != tmp2[idx] {
+			return chr < tmp2[idx]
+		}
+	}
+	return true
+}
+func (a Arr) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+func UTF82GBK(src string) ([]byte, error) {
+	GB18030 := simplifiedchinese.All[0]
+	return ioutil.ReadAll(transform.NewReader(bytes.NewReader([]byte(src)), GB18030.NewEncoder()))
+}
+
+// func main() {
+// 	tmp := Arr{"项目名称", "winner", "省份", "项目编号", "城市", "公告二级", "区县", "项目规模 ", "项目范围", "预算", "中标金额", "采购单位", "采购联系人 ", "中标电话 ", "中标地址 ", "竣工日期 ", "工期时长 ", "工期单位 ", "项目周期(服务周期) ", "评审专家 ", "招标文件购买金额 ", "投标保证金-是否支持保函", "ppp项目", "是否支持保函", "标的物", "多包", "中标候选人"}
+// 	sort.Sort(tmp)
+// 	fmt.Println(tmp)
+// }

+ 2 - 2
src/web/templates/com/menu_second.html

@@ -87,7 +87,7 @@
 {{include "com/footer.html"}}
 
 <script>
-	var pid={{.T.id}};
+	var pid={{ .T.id }}
 	var id="";
     menuActive("menu")
     $(function () {
@@ -101,7 +101,7 @@
             "ajax": {
                 "url": "/front/menuSecond",
                 "type": "post",
-                "data":{"id":{{.T.id}}}
+                "data":{"id": pid }
             },
             "language": {
                 "url": "/dist/js/dataTables.chinese.lang"

+ 103 - 0
src/web/templates/project/check_data_list.html

@@ -0,0 +1,103 @@
+{{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="col-xs-12">
+                <div class="box">
+                    <div class="box-body">
+                        <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=-1>全部</option>
+                                    <option value=0>未标注</option>
+                                    <option value=1>已标注</option>
+                                </select></label>
+                        </div>
+                        <table id="dataTable" class="table table-bordered table-hover">
+                            <thead>
+                            <tr>
+                                <th></th>
+                                <th>标题</th>
+                                <th>用户</th>
+                            </tr>
+                            </thead>
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+</div>
+
+{{include "com/footer.html"}}
+<script>
+    menuActive("/front/user/task/list");
+
+    let tid = {{ .T.tid }}
+    let sourceinfo = {{ .T.sourceinfo }}
+
+    $(function () {
+        ttable = $('#dataTable').dataTable({
+            "paging": true,
+            "lengthChange": false,
+            "searching": true,
+            "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": "v_baseinfo.title", render: function (val, index, row) {
+                        let 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 + '&s_sourceinfo='+sourceinfo+'">' + val + '</a>'
+                        return tmp
+                    }},
+                {"data": "s_login", "defaultContent": ""},
+            ],
+            "initComplete": function () {
+                $("#dataTable_filter").append($('#status-div'))
+            },
+            "fnServerParams": function (e) {
+                e.i_ckdata = $("#statusSelect option:selected").val()
+            }
+        });
+        $('#statusSelect').on('changed.bs.select', function () {
+            ttable.api().ajax.reload();
+        })
+    });
+
+</script>

+ 1470 - 0
src/web/templates/project/check_detail.html

@@ -0,0 +1,1470 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>标注中心</title>
+    <script src="/bower_components/jquery/dist/jquery.min.js"></script>
+    <link href="/dist/css/normalize.min.css" rel="stylesheet">
+    <link href="/dist/css/animate.min.css" rel="stylesheet">
+    <link rel="stylesheet" href="/dist/css/zz.css">
+    <link rel="stylesheet" href="/dist/css/index.css">
+    <script src="/dist/js/vue.min.js"></script>
+    <script src="/dist/js/index.js"></script>
+    <style>
+        .add-tip {
+            width: 24px;
+            height: 22px;
+            line-height: 22px;
+            text-align: center;
+            color: #fff;
+            margin: 0;
+            padding: 0;
+            border: 1px solid #ccc;
+            background-color: #fdfdfd;
+        }
+
+        .info-box > * {
+            cursor: pointer;
+        }
+
+        .button-group {
+            display: flex;
+            flex-direction: row;
+            align-items: center;
+            justify-content: space-between;
+        }
+
+        .button-group .info-box {
+            margin-left: -60px;
+        }
+
+        .edit-box .edit.two .edit-title {
+            padding-right: 4px;
+        }
+
+        .edit-box .edit .edit-input .label > span {
+            max-width: unset;
+            text-align: left;
+            padding: 0 1em;
+        }
+
+        .a-button {
+            color: #4169e3;
+            margin: 8px 15px;
+            padding: 4px 10px;
+        }
+
+        .button-box.delete-box {
+            margin-right: 22px !important;
+            margin-left: -419px !important;
+        }
+
+        .button-box.delete-box .pass {
+            background-color: #f56c6c !important;
+        }
+
+        .pass.success {
+            background-color: #09bb07 !important;
+        }
+
+        .pass.default {
+            background-color: #adadad !important;
+        }
+
+        .el-table td, .el-table th {
+            padding: 4px 0;
+        }
+
+        .top-button-group {
+            margin-top: 20px;
+        }
+
+        .top-button-group button {
+            margin-bottom: 12px;
+        }
+
+        .el-radio-button--mini.info .el-radio-button__inner {
+            color: #909399 !important;
+            background: #f4f4f5 !important;
+            border-color: #d3d4d6 !important;
+        }
+
+        .default .el-radio-button__orig-radio + .el-radio-button__inner {
+            color: #409eff;
+            background: #ecf5ff;
+            border-color: #b3d8ff;
+        }
+
+        .success .el-radio-button__orig-radio + .el-radio-button__inner {
+            color: #67c23a;
+            background: #f0f9eb;
+            border-color: #c2e7b0;
+        }
+
+        .success .el-radio-button__orig-radio:checked + .el-radio-button__inner,
+        .default .el-radio-button__orig-radio:checked + .el-radio-button__inner {
+            color: #FFF;
+            background-color: #409EFF;
+            border-color: #409EFF;
+            -webkit-box-shadow: -1px 0 0 0 #409EFF;
+            box-shadow: -1px 0 0 0 #409EFF
+        }
+
+
+    </style>
+    <script>
+        function prettyPrint(obj) {
+            var ENDLINE = "\n";
+            var COMMA_ENDLINE = ",\n";
+            var OBJ_BEGIN = "{";
+            var OBJ_END = "}";
+            var ARR_BEGIN = "[";
+            var ARR_END = "]";
+            var INDNET_SPACES = 4;
+
+            return (function innerPrettyPrint(obj, spaces) {
+                var type = typeof obj;
+                if (type == "number" || type == "boolean") {
+                    return obj.toString();
+                } else if (type == "string") {
+                    if (obj != "" && !isNaN(Number(obj))) {
+                        return Number(obj)
+                    }
+                    return '"' + obj + '"';
+                } else {
+                    var entries = [];
+                    var thisIndent = ' '.repeat(spaces);
+                    var subIndent = thisIndent + ' '.repeat(INDNET_SPACES);
+                    var subSpaces = spaces + INDNET_SPACES;
+                    if (Object.prototype.toString.call(obj) == '[object Object]') {
+                        for (var k in obj) {
+                            entries.push('"' + k + '": ' + innerPrettyPrint(obj[k], subSpaces));
+                        }
+                        return OBJ_BEGIN + ENDLINE + subIndent + entries.join(COMMA_ENDLINE + subIndent) + ENDLINE + thisIndent + OBJ_END;
+                    } else if (Object.prototype.toString.call(obj) == '[object Array]') {
+                        obj.forEach(function (a) {
+                            entries.push(innerPrettyPrint(a, subSpaces));
+                        });
+                        return ARR_BEGIN + ENDLINE + subIndent + entries.join(COMMA_ENDLINE + subIndent) + ENDLINE + thisIndent + ARR_END;
+                    } else if (obj === null) {
+                        return "null";
+                    } else {
+                        return obj.toString();
+                    }
+                }
+            })(obj, 0);
+        }
+    </script>
+</head>
+<body>
+<main id="app">
+    <div class="content" :class="{mm:showPop}">
+        <!--文章区-->
+        <div class="article">
+            <div class="top-button-group">
+                <el-radio-group v-model="activeLabel" size="mini">
+                    <el-radio-button class="default" label="原文"></el-radio-button>
+                    {{if .T.info.filetext}}
+                    <el-radio-button class="default" label="附件"></el-radio-button>
+                    {{end}}
+                </el-radio-group>
+
+                <el-radio-group v-model="activeLabel" v-for="(item, index) in otherInfo" size="mini">
+                    <el-radio-button class="success" :label="item.id">[[item.subtype]]</el-radio-button>
+                    <el-radio-button class="success" :label="item.id + '-附件'">附件</el-radio-button>
+                </el-radio-group>
+
+                <el-radio-group v-if="moreInfo&&moreInfo.length > 0" size="mini">
+                    <el-popover
+                            placement="right-end"
+                            trigger="hover">
+                        <el-table :data="moreInfo" max-height="300">
+                            <el-table-column width="50" property="subtype" label="类型"></el-table-column>
+                            <el-table-column width="180" property="publishtime" label="发布日期"></el-table-column>
+                            <el-table-column width="220" property="title" label="标题">
+                                <template slot-scope="scope">
+                                    <a href="#" @click="openLink(scope.row.href)">[[scope.row.title]]</a>
+                                </template>
+                            </el-table-column>
+                        </el-table>
+                        <el-radio-button class="info" slot="reference" style="border-color: #d3d4d6;">更多
+                        </el-radio-button>
+                    </el-popover>
+                </el-radio-group>
+            </div>
+
+            <hr style="border: 1px;" width="100%">
+            <br><a v-if="getPageInfo.href.length > 0" :href="getPageInfo.href" target="_blank">查看原文</a>
+            <!--<a href="{{.T.jyhref}}" target="_blank">剑鱼链接</a>-->
+            <h3>[[getPageInfo.title]]</h3><br>
+
+            <div v-html="pageHtml"></div>
+        </div>
+        <!--操作区-->
+        <div class="operation">
+            <!--edit-box-->
+            <div class="edit-box">
+                <!--edit-->
+                <div class="edit one" v-for="(one,oindex) in editData" :key="oindex">
+                    <!--one-->
+                    <div class="edit-title" @click="one.show = !one.show">
+                        <span>[[one.title]]</span>
+                        <div class="button-group">
+                            <div v-if="one.showCheck">
+                                <input :id="one.title" v-show="one.title == '标的信息'" @click.stop type="checkbox"
+                                       v-model="one.checkAllTag">
+                                <label @click.stop v-show="one.title == '标的信息'" :for="one.title">全部标注</label>
+                            </div>
+                            <!-- &nbsp;
+                             <div v-if="one.showCheck">
+                                 <input :id="one.title" @click.stop type="checkbox" v-model="one.checkType">
+                                 <label @click.stop :for="one.title">是否抽取</label>
+                             </div>-->
+                            <div class="button-box">
+                                <!--v-show="one.title == '基本字段'"-->
+                                <button class="pass success" @click.stop="saveDataOne(one,'1')"
+                                        style="font-size: 14px;width: auto;float:left;">通过
+                                </button>
+                                <button class="pass default" @click.stop="saveDataOne(one,'-1')"
+                                        style="font-size: 14px;width: auto;float:left">取消
+                                </button>
+                                <!--              						  <button class="pass" @click.stop="open(one, true)"  style="font-size: 14px;width: auto;float:left">保存</button>-->
+                            </div>
+                            <!--<button class="add" v-show="one.title != '基本'" @click.stop="one.content.push(getTemp(2));goMark2(500)">+</button>-->
+                            <!--<button class="add" v-show="one.title == '基本'" @click.stop="one.content[0].content.push(getTemp(3));goMark2(60)">+</button>-->
+                            <div class="info-box" @click.stop v-show="one.showCheck">
+                                <div :class="{default: one.status == '-1'}" @click="setStatus(one,'-1')"></div>
+                                <!--<div :class="{ok: one.status == '1'}" @click="one.status = '1'"></div>-->
+                                <div :class="{ok: one.status == '1'}" @click="setStatus(one,'1')"></div>
+                                <!--<div :class="{err: one.status == '0'}" @click="one.status = '0'"></div>-->
+                                <div class="add-tip" :class="{err: (one.status != '1' && one.status != '-1')}"
+                                     @click="setStatus(one,'2')"></div>
+                            </div>
+
+                        </div>
+                    </div>
+                    <transition tag="div">
+                        <div>
+                            <div class="button-box" v-if="one.showCheck&&one.show">
+                                <button class="pass a-button" @click.stop="addChild(one, oindex)"
+                                        style="font-size: 14px;width: auto;float:left;">新增[[one.title]]
+                                </button>
+                            </div>
+                            <div class="edit-content" :class="{t:one.title == '基本字段'}" v-show="one.show">
+                                <!--two-->
+
+                                <span v-show="one.content.length === 0">当前您还没有添加子包</span>
+                                <div class="edit two" v-for="(two,index) in one.content" :key="index">
+                                    <div class="edit-title" v-if="two.title" @click="two.show = !two.show">
+                                        <span>[[two.title]]</span>
+                                        <div class="button-box"
+                                             :style="one.title == '多包信息' ? 'margin-right: 193px' : ''">
+                                            <button v-if="one.title == '多包信息'" class="pass a-button"
+                                                    @click.stop="addThreeChild(two,'2',one)"
+                                                    style="font-size: 14px;margin: 0;width: auto;float:left;">新增子包中标信息
+                                            </button>
+                                            <button class="pass success" @click.stop="saveDataTwo(two,'1',one)"
+                                                    style="font-size: 14px;width: auto;float:left;">通过
+                                            </button>
+                                            <button class="pass default" @click.stop="saveDataTwo(two,'-1',one)"
+                                                    style="font-size: 14px;width: auto;float:left">取消
+                                            </button>
+                                        </div>
+                                        <div class="button-box delete-box">
+                                            <button class="pass" @click.stop="delNewTwo(one, index, two)">删除</button>
+                                        </div>
+                                    </div>
+                                    <transition tag="div">
+                                        <div class="edit-content" v-show="two.show">
+                                            <!--input-->
+                                            <div class="edit-input">
+                                                <div v-for="(uin, uindex) of two.uInput" class="input-box"
+                                                     :key="uin.title">
+                                                    <div class="label" v-if="uin.selectArr">
+                                                        <span>[[uin.title]]&nbsp;:&nbsp;</span>
+                                                        <select v-model="uin.select"
+                                                                @change="focusFn(uin, oindex,index,uindex, two, one)">
+                                                            <option disabled value="">请选择</option>
+                                                            <option v-for="o in uin.selectArr">[[o]]</option>
+                                                        </select>
+                                                        <div class="info-box">
+                                                            <div :class="{default: uin.status == '-1'}"
+                                                                 @click="setStatus(uin,'-1', two, one)"></div>
+                                                            <div :class="{ok: uin.status == '1'}"
+                                                                 @click="setStatus(uin,'1', two, one)"></div>
+                                                            <!--<div :class="{err: uin.status == '0'}" @click="uin.status = '0'"></div>-->
+                                                            <div class="add-tip" @click="setStatus(uin,'2', two, one)"
+                                                                 :class="{err: (uin.status != '1' && uin.status != '-1')}"></div>
+
+                                                        </div>
+                                                    </div>
+                                                    <div class="label" v-else :title="uin.input">
+                                                        <span @click="goText(uin.title)">[[uin.title]]&nbsp;:&nbsp;</span>
+                                                        <input type="text" v-model="uin.input"
+                                                               @focus="goText(uin.input)" @click="goText(uin.input)"
+                                                               @blur="focusFn(uin, oindex, index, uindex,two,one)">
+                                                        <div class="info-box">
+                                                            <div :class="{default: uin.status == '-1'}"
+                                                                 @click="setStatus(uin,'-1', two, one)"></div>
+                                                            <div :class="{ok: uin.status == '1'}"
+                                                                 @click="setStatus(uin,'1', two, one)"></div>
+                                                            <!--<div :class="{err: uin.status == '0'}" @click="uin.status = '0'"></div>-->
+                                                            <div class="add-tip" @click="setStatus(uin,'2', two, one)"
+                                                                 :class="{err: (uin.status != '1' && uin.status != '-1')}"></div>
+
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                            <!--three-->
+                                            <!--<div>
+                                                                     <div class="edit-title" v-show="one.title == '基本字段'">
+                                                    <span>候选人</span>
+                                                    <div class="info-box" >
+                                                        <div :class="{default: two.wstatus == '-1'}" @click="two.wstatus = '-1'"></div>
+                                                        <div :class="{ok: two.wstatus == '1'}" @click="two.wstatus = '1'"></div>
+                                                        <el-popover trigger="click" >
+                                                          <div style="text-align: right; margin: 0">
+                                                            <el-button type="success" size="mini" @click="two.wstatus = '2'">新增</el-button>
+                                                            <el-button type="warning" size="mini" @click="two.wstatus = '3'">修改</el-button>
+                                                            <el-button type="danger" size="mini" @click="two.wstatus = '4'">删除</el-button>
+                                                          </div>
+                                                          <div class="add-tip" slot="reference" :class="{err: (two.wstatus != '1' && two.wstatus != '-1')}">[[textMap[two.wstatus] || '']]</div>
+                                                        </el-popover>
+                                                    </div>
+                                                </div>
+                                                <div class="edit three" v-for="(three,index) in two.content" :key="index">
+                                                    <div class="edit-title" @click="three.show = !three.show">
+                                                        <span>[[three.title]]</span>
+                                                    </div>
+                                                    <div class="edit-content" v-show="three.show">
+                                                        <div class="edit-input">
+                                                            <div class="input-box" v-for="(threeUin,index) in three.uInput" :key="threeUin.title">
+                                                                <div class="label">
+                                                                    <span @click="goText(threeUin.title)">[[threeUin.title]]&nbsp;:&nbsp;</span>
+                                                                    <input type="text" v-model="threeUin.input" @focus="goText(threeUin.input)" @click="goText(threeUin.input)">
+                                                                    <div class="info-box">
+                                                                        <div :class="{default: threeUin.status == '-1'}" @click="threeUin.status = '-1'"></div>
+                                                                        <div :class="{ok: threeUin.status == '1'}" @click="threeUin.status = '1'"></div>
+                                                                      <el-popover trigger="click" >
+                                                                        <div style="text-align: right; margin: 0">
+                                                                          <el-button type="success" size="mini" @click="threeUin.status = '2'">新增</el-button>
+                                                                          <el-button type="warning" size="mini" @click="threeUin.status = '3'">修改</el-button>
+                                                                          <el-button type="danger" size="mini" @click="threeUin.status = '4'">删除</el-button>
+                                                                        </div>
+                                                                        <div class="add-tip" slot="reference" :class="{err: (threeUin.status != '1' && threeUin.status != '-1')}">[[textMap[threeUin.status] || '']]</div>
+                                                                      </el-popover>
+                                                                    </div>
+                                                                </div>
+                                                            </div>
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            </div>-->
+
+                                        </div>
+                                    </transition>
+                                </div>
+                            </div>
+                        </div>
+                    </transition>
+                </div>
+            </div>
+            <div class="save-box">
+<!--                 <button  class="code" @click.stop="showPop = true" style="width:100px">源码</button>&nbsp;&nbsp;-->
+                <!--                 <button  class="code" @click.stop="open(1)" style="width:100px">全部验证</button> -->
+<!--                <button class="code" @click.stop="open(2)" style="width:100px">字段验证</button>-->
+                <button  class="code" @click.stop="open('', false)" style="width:100px">保存</button>&nbsp;&nbsp;
+                <button class="code" @click.stop="openHref" style="width:100px">下一条</button>
+                <!--<button  class="code" @click.stop="window.location.href='/'" style="width:100px">下一条</button>-->
+            </div>
+        </div>
+    </div>
+    <!--弹出层-->
+    <dialog class="dialog" v-if="showPop">
+        <span class="close" @click="showPop = false;changeText()">x</span>
+        <div class="pop">
+            <div class="title">源码</div>
+            <div class="con" ref="text" contentEditable="true">
+                <pre v-html="addStyle(editData)"></pre>
+            </div>
+            <button @click="showPop = false;changeText();upChange()">保&nbsp;存</button>
+        </div>
+    </dialog>
+    <dialog id="com-alert" class="dialog" style="background: rgba(124, 124, 125, 0.1);z-index:9999;display: none;">
+        <div class="pop" style="background: rgba(124, 124, 125, 0.1);">
+            <div id="com-alert-val" class="title" style="color:red">保存成功</div>
+        </div>
+    </dialog>
+</main>
+
+</body>
+
+<script>
+    let tid = {{ .T.tid }}      // 任务id
+    let did = {{ .T.did }}      // 数据id
+    let pid = {{ .T.pid }}      // 项目id
+    let coll = {{ .T.coll }}    // 表名
+    var allCheckFields = {{ .T.fields }}          //本次需标注的所有字段
+    console.log(allCheckFields)
+    var moreInfo = {{ .T.moreInfo }}            // 更多关联信息
+    var otherInfo = {{ .T.otherInfo }}          //公告关联信息
+
+    let purchasing_status = {{ .T.ck_purchasinglist }}      //标的物标记
+    let purchasing_all_tag = {{ .T.ck_pclistag }}           // 标的物是否全部标记
+    let package_status = {{ .T.ck_package }}                //包标记
+    let winneroder_status = {{ .T.ck_winnerorder }}         //中标候选人标记
+    // 页面数据
+    var pageDataMap = {
+        '原文': {
+            title: '{{.T.info.title}}',
+            href: '{{.T.info.href}}',
+            // html: '{{Html (Regexp (Regexp .T.info.detail "(\\n|\\\\n)\\s+" "\n") "(`|\\n|\\\\n)+" "<br/>")}}',
+            html: '{{ .T.info.detail }}',
+        },
+        '附件': {
+            title: '附件内容',
+            href: '',
+            // html:{{if .T.info.filetext}}{{.T.info.filetext}}.replace(/(\\n|\\\\n)\\s+/, '\n').replace(/(`|\\n|\\\\n)+/, '<br>'){{else}}``{{end}} }
+            html: '{{ .T.info.filetext }}',
+        },
+    }
+
+    //快捷键
+    $(document).keydown(function (event) {
+        if (!event.shiftKey) {
+            var text = getSelectedContents();//获取选中文本
+            if (!text.trim().length) {
+                return
+            }
+        }
+
+        if (event.keyCode === 82) {//项目名称快捷键r
+            if (event.shiftKey) {
+                app.changeBaseValue(0, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(0, text, 2)//填充
+            }
+        } else if (event.keyCode === 81) {//省份快捷键q
+            if (event.shiftKey) {
+                app.changeBaseValue(1, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(1, text, 2)//填充
+            }
+        } else if (event.keyCode === 84) {//项目编号快捷键t
+            if (event.shiftKey) {
+                app.changeBaseValue(2, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(2, text, 2)//填充
+            }
+        } else if (event.keyCode === 87) {//城市快捷键w
+            if (event.shiftKey) {
+                app.changeBaseValue(3, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(3, text, 2)//填充
+            }
+        } else if (event.keyCode === 69) {//区县快捷键e
+            if (event.shiftKey) {
+                app.changeBaseValue(5, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(5, text, 2)//填充
+            }
+        } else if (event.keyCode === 65) {//预算快捷键a
+            if (event.shiftKey) {
+                app.changeBaseValue(6, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(6, text, 2)//填充
+            }
+        } else if (event.keyCode === 90) {//中标金额快捷键z
+            if (event.shiftKey) {
+                app.changeBaseValue(7, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(7, text, 2)//填充
+            }
+        } else if (event.keyCode === 83) {//采购单位快捷键s
+            if (event.shiftKey) {
+                app.changeBaseValue(8, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(8, text, 2)//填充
+            }
+        } else if (event.keyCode === 88) {//代理机构快捷键x
+            if (event.shiftKey) {
+                app.changeBaseValue(9, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(9, text, 2)//填充
+            }
+        } else if (event.keyCode === 68) {//中标单位快捷键d
+            if (event.shiftKey) {
+                app.changeBaseValue(10, '', 2) //删除对应文本
+            } else {
+                app.changeBaseValue(10, text, 2)//填充
+            }
+        }
+    });
+
+    //获取鼠标选中的文本
+    function getSelectedContents() {
+        var text = "";
+        if (window.getSelection) { //chrome,firefox,opera
+            var range = window.getSelection().getRangeAt(0);
+            var container = document.createElement('div');
+            container.appendChild(range.cloneContents());
+            text = container.innerHTML;
+            //return container.innerHTML;
+            //return window.getSelection(); //只复制文本
+        } else if (document.getSelection) { //其他
+            var range = document.getSelection().getRangeAt(0);
+            var container = document.createElement('div');
+            container.appendChild(range.cloneContents());
+            text = container.innerHTML;
+            //return container.innerHTML;
+            //return document.getSelection(); //只复制文本
+        } else if (document.selection) { //IE特有的
+            text = document.selection.createRange().htmlText;
+            //return document.selection.createRange().htmlText;
+            //return document.selection.createRange().text; //只复制文本
+        }
+        text = text.replace(/(\r|\n|\s+|&nbsp;|<[^>]*>|<\/[^>]*)/g, "")
+        return text;
+    }
+
+    //记录是否点击保存
+    var issave = false;
+    var _id = {{ .T.did }}
+    var nextid = {{ .T.nextid }}
+    //基本信息
+    var common = {{ .T.common }}
+    var uInput = [];
+    for (k in common) {
+        var tmp = {}
+        tmp.title = common[k].descript
+        tmp.input = common[k].value
+        tmp.key = common[k].key
+        if (common[k].key === "subtype") {
+            tmp.select = common[k].value
+            tmp.selectArr = {{ .T.topsubtype }}
+        }
+        if (common[k].key === "attach_discern") {
+            tmp.select = common[k].value
+            tmp.selectArr = ['识别有效', '识别无效']
+        }
+        if (common[k].key === "attach_ext") {
+            tmp.select = common[k].value
+            tmp.selectArr = ['抽取正确', '抽取错误']
+        }
+        if (common[k].key === "isrepeat") {
+            tmp.select = common[k].value
+            tmp.selectArr = ['是', '否']
+        }
+        tmp.status = common[k].status
+        if (common[k].key === "bidamounttype") {
+            tmp.select = common[k].value ? common[k].value : '金额'
+            tmp.selectArr = ['金额', '折扣率', '单价']
+            tmp.status = 1
+        }
+        uInput[k] = tmp
+    }
+    //时间地点
+    var timeplace = {{ .T.timeplace }}
+    var tpInput = [];
+    for (k in timeplace) {
+        var tmp = {}
+        tmp.title = timeplace[k].descript
+        tmp.input = timeplace[k].value
+        tmp.key = timeplace[k].key
+        tmp.status = timeplace[k].status
+        tpInput[k] = tmp
+    }
+
+    //其他信息
+    var other = {{ .T.other }}
+    var otherInput = [];
+    for (k in other) {
+        var tmp = {}
+        tmp.title = other[k].descript
+        tmp.input = other[k].value
+        tmp.key = other[k].key
+        tmp.status = other[k].status
+        if (other[k].key === "isppp" || other[k].key === "contract_guarantee" || other[k].key === "bid_guarantee") {
+            tmp.select = other[k].value
+            tmp.selectArr = ['是', '否']
+        }
+        otherInput[k] = tmp
+    }
+
+    //中标候选人
+    var c_worder = {{ .T.worder }}
+    var worder_new = {{ .T.worder_new }}
+    var c_content = [];
+    for (k in c_worder) {
+        var c_uInput = [];
+        for (i in c_worder[k]) {
+            var tmp = {}
+            tmp.title = c_worder[k][i].descript
+            tmp.input = c_worder[k][i].value || ''
+            tmp.key = c_worder[k][i].key
+            tmp.status = c_worder[k][i].status
+            c_uInput[i] = tmp
+        }
+        var content = {};
+        content.title = "候选人"
+        content.show = true
+        content.status = worder_new[k]["status"]
+        content.uInput = c_uInput
+        content.isnew = worder_new[k]["isnew"] || false
+        content.content = []
+        c_content[k] = content
+    }
+
+    //标的信息
+    var purchasinglist = {{ .T.purchasinglist }}
+    var pcl_new = {{ .T.pcl_new }}
+    var pcl_content = [];
+    for (k in purchasinglist) {
+        var c_uInput = [];
+        for (i in purchasinglist[k]) {
+            var tmp = {}
+            tmp.title = purchasinglist[k][i].descript
+            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 = {};
+        content.title = "标的物"
+        content.show = true
+        content.status = pcl_new[k]["status"]
+        content.uInput = c_uInput
+        content.isnew = pcl_new[k]["isnew"] || false
+        content.content = []
+        pcl_content[k] = content
+    }
+
+    //var ispackage='{{.T.ispackage}}'
+    //子包信息
+    var packs = {{ .T.packs }}
+    var packskey = {{ .T.packskey }}
+    var pkg_new = {{ .T.pkg_new }}
+    //分包抽查,若果有分包,默认ok
+    //if(packs.length>0&&ispackage=="1"){
+    //	ck_package="1"
+    //}
+    var p_content = [];
+    for (k in packs) {
+        //子包基本信息
+        var uInputs = [];
+        var pack = packs[k]["pack"]
+        for (i in pack) {
+            var tmp = {}
+            tmp.title = pack[i].descript
+            tmp.input = pack[i].value
+            tmp.key = pack[i].key
+            tmp.status = pack[i].status
+            if (pack[i].key === "bidamounttype") {
+                tmp.select = pack[i].value ? pack[i].value : '金额'
+                tmp.selectArr = ['金额', '折扣率', '单价']
+                tmp.status = 1
+            }
+            uInputs[i] = tmp
+        }
+
+        //中标人信息
+        var winnerall = packs[k]["winnerall"]
+        for (i in winnerall) {
+            var tmp = {}
+            tmp.title = winnerall[i].descript
+            tmp.input = winnerall[i].value
+            tmp.key = winnerall[i].key
+            tmp.status = winnerall[i].status
+            uInputs.push(tmp)
+        }
+        var content = {};
+        content.title = "子包";
+        content.show = true;
+        content.status = packs[k]["packstatus"];
+        content.uInput = uInputs;
+        content.isnew = pkg_new[k] || false
+        content.num = packskey[k];
+        p_content[k] = content;
+
+    }
+
+    var pclf = {{ .T.PurchasinglistField }}
+    var pclfInput = []
+    for (i in pclf) {
+        for (key in pclf[i]) {
+            var tempNode = {
+                input: "",
+                key: key,
+                status: "2",
+                title: pclf[i][key]
+            }
+            //if(key== "pclisover"){
+            //  tempNode.select= '是'
+            //  tempNode.selectArr=['是','否']
+            //}
+            pclfInput.push(tempNode)
+        }
+    }
+
+
+    var wodf = {{ .T.WinnerorderField }}
+    var wodfInput = []
+    for (i in wodf) {
+        for (key in wodf[i]) {
+            wodfInput.push({
+                input: "",
+                key: key,
+                status: "2",
+                title: wodf[i][key]
+            })
+        }
+    }
+    var pf = {{ .T.PackageField }}
+    var pfInput = []
+    for (i in pf) {
+        for (key in pf[i]) {
+            var tempNode = {
+                input: "",
+                key: key,
+                status: "2",
+                title: pf[i][key]
+            }
+            if (key === "bidamounttype") {
+                tempNode.select = '金额'
+                tempNode.selectArr = ['金额', '折扣率', '单价']
+            }
+            pfInput.push(tempNode)
+        }
+    }
+    var app = new Vue({
+        el: '#app',
+        delimiters: ["[[", "]]"],
+        data: {
+            activeLabel: '原文',
+            nowLabel: ['原文'],
+            otherInfo: otherInfo,
+            moreInfo: moreInfo,
+            scrollCache: {
+                value: '',
+                index: 0
+            },
+            textMap: ['', '', '增', '改', '删'],
+            // pageHtml: `{{Html (Regexp (Regexp .T.info.detail "(\\n|\\\\n)\\s+" "\n") "(`|\\n|\\\\n)+" "<br/>")}}`,
+            pageHtml: '{{ .T.info.detail }}',
+            showPop: false,
+            editData:[{
+                title: '基本字段',
+                show: true,
+                status: "1",
+                content: [{
+                    title: '',
+                    show: true,
+                    delete: false,
+                    //wstatus:"-1",
+                    uInput: uInput
+                    //content: c_content
+                    }]
+                }, {
+                title: '时间地点',
+                show: false,
+                status: "1",
+                content: [{
+                    title: '',
+                    show: true,
+                    delete: false,
+                    //wstatus:"-1",
+                    uInput: tpInput
+                    }]
+                }, {
+                title: '标的信息',
+                show: false,
+                showCheck: true,
+                key: 'purchasinglist',
+                //checkType: {{.T.ck_pclisext}},
+                checkAllTag: purchasing_all_tag,
+                status: purchasing_status,
+                content: pcl_content
+                }, {
+                title: '多包信息',
+                show:false,
+                showCheck: true,
+                key: 'package',
+                // checkType: {{.T.ck_pkgisext}},
+                status: package_status,
+                content: p_content
+                }, {
+                title: '中标候选人信息',
+                show: false,
+                showCheck: true,
+                key: 'winnerorder',
+                // checkType: {{.T.ck_wodrisext}},
+                status: winneroder_status,
+                content: c_content
+                }, {
+                title: '其余信息',
+                show:false,
+                status:"1",
+                content:[{
+                    title: '',
+                    show: true,
+                    delete: false,
+                    //wstatus:"-1",
+                    uInput: otherInput
+                  }]
+                }],
+            originData: []},
+            watch: {
+                //切换标签时更改正文内容
+                'activeLabel':
+                function () {
+                    this.pageHtml = this.getPageInfo.html
+                }},
+            computed: {
+                getPageInfo() {
+                    var tempData = {
+                        title: '',
+                        html: this.pageHtml,
+                        href: ''
+                    }
+                    //匹配原文或者原文附件
+                    var originData = pageDataMap[this.activeLabel]
+                    if (originData) {
+                        tempData.title = originData.title
+                        tempData.html = originData.html
+                        tempData.href = originData.href
+                    } else {//匹配原公告关联信息
+                        var tempS = this.activeLabel.split('-')
+                        var isFile = tempS.length === 2
+                        var otherData = this.otherInfo.filter(v => v.id == tempS[0])
+                        if (otherData.length > 0) {
+                            tempData.title = otherData[0].title
+                            tempData.html = otherData[0].detail
+                            tempData.href = otherData[0].href
+                            if (isFile) {
+                                tempData.title = '附件内容'
+                                tempData.html = otherData[0].filetext
+                                tempData.href = ''
+                            }
+                        }
+                    }
+                    return tempData
+                }
+            },
+            mounted() {
+                // 缓存原始数据
+                this.originData = JSON.parse(JSON.stringify([].concat(this.editData)))
+            },
+            methods: {
+                // 当前输入框数据与原始数据比较
+                focusFn(uin, oIndex, tIndex, uIndex, two, one) {
+                    if (uin.key === "bidendtime" || uin.key === "bidopentime" || uin.key === "project_startdate" || uin.key === "project_completedate" ||
+                        uin.key === "publishtime" || uin.key === "signaturedate") {
+                        var val = uin.input
+                        if (val !== "") {
+                              var reg = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/;
+                              var regExp = new RegExp(reg);
+                              if (!regExp.test(val)) {
+                                  this.$message({
+                                      message: uin.title + ",日期格式错误!正确格式:2006-01-02 15:04:05",
+                                      type: 'warning',
+                                      duration: 2000,
+                                      offset: 300
+                                  });
+                                  return
+                            }
+                        }
+                    }
+                    var newNode = this.originData[oIndex].content[tIndex]
+                    if (newNode == null) {//新增子模块处理
+                        return
+                    }
+                    var oNode = newNode.uInput[uIndex]
+                    if (oNode == null) {//新增中标人信息处理
+                        return
+                    }
+                    var changeStatus = uin.input === oNode.input//多包中新增的中标信息报错
+                    if (uin.select) {
+                        changeStatus = uin.select === oNode.select
+                    }
+                    uin.status = changeStatus ? "1" : "2"
+                        this.setStatus(uin, uin.status, two, one);
+                    },
+                openLink(link) {
+                        window.open(link, '_blank')
+                    },
+                // 改变基本字段属性
+                changeBaseValue(index, input, status) {
+                    if (this.editData[0].content[0].uInput[index].input !== input) {
+                        this.editData[0].content[0].uInput[index].input = input
+                        this.editData[0].content[0].uInput[index].status = status
+                    }
+                },
+                selectChange(uni, status, two, one) {
+                        //状态更新
+                        if (uni.status === '-1' || uni.status === '2') {
+                            status = "2"
+                        }
+                        this.setStatus(uni, status, two, one)
+                    },
+                openHref() {
+                    if (!issave) {
+                        alert("请先保存数据!")
+                    } else {
+                        if (nextid === "") {
+                            showMsg("数据已经全部标注完")
+                        } else {
+                            window.location.href = "/front/user/remark/list?pid="+pid+"&tid="+tid+"&s_sourceinfo="+coll
+                        }
+                    }
+                },
+                // 检查一级是否需要改变状态
+                checkOneStatus: function (config) {
+                    var tempObj = {
+                        obj: config.type ? config.one : config.two
+                    }
+                    if (config.type) {
+                        tempObj.list = config.one.content
+                    } else {
+                        tempObj.list = config.two.uInput
+                    }
+                    var statusList = [0, 0, 0, 0, 0]
+                    for (var i in tempObj.list) {
+                    var tempList = tempObj.list[i]
+                    var tempIndex = Number(tempList.status)
+                    if (tempIndex === -1) {
+                        tempIndex = 0
+                    }
+                        statusList[tempIndex] = Number(statusList[tempIndex]) + 1
+                    }
+                    if (statusList[1] > 0) {
+                        tempObj.obj.status = "1"
+                    }
+                    if (statusList[4] > 0 || statusList[3] > 0 || statusList[2] > 0) {
+                        tempObj.obj.status = "2"
+                    }
+                    if (statusList[4] === tempObj.list.length) {
+                        tempObj.obj.status = "4"
+                    if (tempObj.obj.title === "标的信息" || tempObj.obj.title === "多包信息" || tempObj.obj.title === "中标候选人信息") {
+                        tempObj.obj.status = "2"
+                        }
+                    }
+                    if (statusList[3] === tempObj.list.length) {
+                        tempObj.obj.status = "2"
+                    }
+                    if (statusList[2] === tempObj.list.length) {
+                        tempObj.obj.status = "2"
+                    }
+                    if (statusList[0] === tempObj.list.length) {
+                        tempObj.obj.status = "-1"
+                    }
+                    if (!config.type) {
+                        this.checkOneStatus({
+                            one: config.one,
+                            two: config.two,
+                            type: true
+                        })
+                    }
+                },
+                //切换状态按钮
+                setStatus:function (witch, s, two, one) {
+                    var key = witch.key
+                    //校验日期格式
+                    if (key === "bidendtime" || key === "bidopentime" || key === "project_startdate" || key === "project_completedate" ||
+                        key === "publishtime" || key === "signaturedate") {
+                        var val = witch.input
+                        if (val !== "") {
+                            var reg = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/;
+                            var regExp = new RegExp(reg);
+                            if (!regExp.test(val)) {
+                                this.$message({
+                                    message: witch.title + ",日期格式错误!正确格式:2006-01-02 15:04:05",
+                                    type: 'warning',
+                                    duration: 2000,
+                                    offset: 300
+                                });
+                                //alert(witch.title+",日期格式错误!正确格式:2006-01-02 15:04:05")
+                                return
+                            }
+                        }
+                    }
+                    if (s === '2' && !one && !two && witch.content.length === 0) {
+                        return
+                    }
+                    witch.status = s;
+                    if (two) {
+                        this.checkOneStatus({
+                            one: one,
+                            two: two,
+                            type: false
+                        })
+                    }
+                },
+                //二级删除
+                delNewTwo: function (one, index, two) {
+                    //two.ck_isnew = false //目前点删除按钮页面直接不显示,但是集合索引位置不变,所以加了此代码
+                    //two.show = false
+                    if (two.isnew) {
+                        one.content.splice(index, 1)
+                    } else {
+                        two.show = false
+                        two.status = "4"
+                        this.saveDataTwo(two, "4", one)
+                    }
+                    this.checkOneStatus({
+                        one: one,
+                        two: two,
+                        type: true
+                    })
+                },
+                /*add style*/
+                addStyle: function (data) {
+                    return prettyPrint(data).replace(/(checkAllTag|checkType|showCheck|wstatus|status|key|title|input|content|uInput|selectArr|select|show|true)/g, "<mark>$1</mark>")
+                },
+                /*同步修改源码*/
+                changeText: function (boolean) {
+                    try {
+                        var tempText = JSON.parse(this.$refs.text.innerText.replace(/(\n|\s)/g, ''))
+                        if (boolean) {
+                            this.tagvalues = tempText
+                        } else {
+                            this.editData = tempText
+                        }
+                    } catch (err) {
+                        alert('源码修改失败')
+                    }
+                },
+                goText: function (value) {
+                    /*重置Html*/
+                    this.pageHtml = this.getPageInfo.html
+                    if (!value) {
+                        return false
+                    }
+                    var rs = new RegExp('(' + value + ')', 'gi')
+                    //选中input框值文本高亮
+                    if (rs.test(this.pageHtml)) {
+                        this.pageHtml = this.pageHtml.replace(rs, '<mark>$1</mark>')
+                        /*延迟查询dom,防止dom未插入*/
+                        var $this = this
+                        setTimeout(function () {
+                            $this.goMark(value)
+                        }, 150)
+                    } else {
+                        /*重置Html*/
+                        this.pageHtml = this.getPageInfo.html
+                    }
+                },
+                goMark: function (value) {
+                    var mLength = document.querySelectorAll('mark').length
+                    if (this.scrollCache.value === value) {
+                        this.scrollCache.index = (this.scrollCache.index + 1) % mLength
+                    } else {
+                        this.scrollCache.index = 0
+                    }
+                    this.scrollCache.value = value
+                    /*滚动到第一个mark*/
+                    var temp = document.querySelectorAll('mark')[this.scrollCache.index]
+                    $("mark").removeClass('focus')
+                    $(temp).addClass('focus')
+                    document.querySelector('.article').scrollTop = offset(temp).top - window.screen.height / 2
+                },
+                // markTag:function(n){
+                //    $.ajax({
+                //        url:"/markTag",
+                //        method:"post",
+                //        data: {tag:n,_id:_id},
+                //        success:function(res){
+                //            if(res){
+                //                document.getElementById("com-alert-val").innerHtml="标记成功";
+                //                var label1 = document.getElementById("com-alert");
+                //                label1.style.display="block";
+                //                setTimeout(function(){label1.style.display="none";},1000)
+                //            }
+                //        }
+                //    });
+                // },
+                addChild: function (one, oindex) {
+                    var tempNode = {}
+                    switch (one.title) {
+                        case "标的信息": {
+                            tempNode = {
+                                //content: [],
+                                show: true,
+                                isnew: true,
+                                status: "2",
+                                title: "标的物",
+                                uInput: JSON.parse(JSON.stringify(pclfInput))
+                            }
+                            break
+                        }
+                        case "多包信息": {
+                            tempNode = {
+                                //content: [],
+                                show: true,
+                                status: "2",
+                                isnew: true,
+                                title: "子包",
+                                uInput: JSON.parse(JSON.stringify(pfInput))
+                            }
+                            break
+                        }
+                        case "中标候选人信息": {
+                            tempNode = {
+                                //content: [],
+                                show: true,
+                                status: "2",
+                                isnew: true,
+                                title: "候选人",
+                                uInput: JSON.parse(JSON.stringify(wodfInput))
+                            }
+                            break
+                        }
+                    }
+                    // if (one.status >= "2") {
+                    //     one.status = '2'
+                    // }
+                    one.content.push(tempNode)
+                    this.checkOneStatus({
+                        one: one,
+                        type: true
+                    })
+                    this.$nextTick(() => {
+                        var tempN = $(".edit.one").eq(oindex).find(".edit-title")
+                        var goTop = tempN.eq(tempN.length - 1).offset().top
+                        setTimeout(() => {
+                            $(".operation").scrollTop($(".operation").scrollTop() + goTop)
+                        }, 150)
+                    })
+                },
+                // 新增子包中标信息字段
+                addThreeChild:function (two, n, one) {
+                    two.uInput.push({
+                        input: "",
+                        key: 'winner',
+                        status: "2",
+                        title: '标段(包)中标单位'
+                    })
+                    two.uInput.push({
+                        input: "",
+                        key: 'bidamount',
+                        status: "2",
+                        title: '标段(包)中标金额'
+                    })
+                    two.status = "2"
+                    this.checkOneStatus({
+                        one: one,
+                        two: two,
+                        type: false
+                    })
+                },
+                //保存
+                saveDataTwo:function (two, n, one) {
+                    two.uInput.forEach(function (v) {
+                        var key = v.key
+                        if (key === "bidendtime" || key === "bidopentime" || key === "project_startdate" || key === "project_completedate" ||
+                            key === "publishtime" || key === "signaturedate") {
+                            var val = v.input
+                            if (val !== "") {
+                                var reg = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/;
+                                var regExp = new RegExp(reg);
+                                if (!regExp.test(val)) {
+                                    this.$message({
+                                        message: v.title + ",日期格式错误!正确格式:2006-01-02 15:04:05",
+                                        type: 'warning',
+                                        duration: 2000,
+                                        offset: 300
+                                    });
+                                    //alert(v.title+",日期格式错误!正确格式:2006-01-02 15:04:05")
+                                    return
+                                }
+                            }
+                        }
+                        if (n === "1" && v.status === "-1") {
+                            v.status = n
+                        } else if (n === "-1") {
+                            v.status = n
+                        } else if (n === "2") {
+                            v.status = n
+                        } else if (n === "4") {
+                            v.status = n
+                        }
+                    });
+                    two.status = n
+                    this.checkOneStatus({
+                        one: one,
+                        two: two,
+                        type: false
+                    })
+                  /**
+                   two.content.forEach(function(v) {
+                      v.uInput.forEach(function(value) {
+                          if (value.input && value.input != '') {
+                              value.status = n
+                          }
+                      })
+                  })
+                   */
+                },
+                saveDataOne:function (one, n) {
+                    //保存后的样式
+                    var _this = this
+                    one.content.forEach(function (v) {
+                        v.uInput.forEach(function (value) {
+                            var key = value.key
+                            if (n === "1") {
+                                if (key === "bidendtime" || key === "bidopentime" || key === "project_startdate" || key === "project_completedate" ||
+                                    key === "publishtime" || key === "signaturedate") {
+                                    var val = value.input
+                                    if (val !== "") {
+                                        var reg = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/;
+                                        var regExp = new RegExp(reg);
+                                        if (!regExp.test(val)) {
+                                            this.$message({
+                                                message: value.title + ",日期格式错误!正确格式:2006-01-02 15:04:05",
+                                                type: 'warning',
+                                                duration: 2000,
+                                                offset: 300
+                                            });
+                                            //alert(value.title+",日期格式错误!正确格式:2006-01-02 15:04:05")
+                                            return
+                                        }
+                                    }
+                                }
+                            }
+                            // 取消全部,通过时判断状态是否处于修改新增等
+                            if (n === "1" && value.status === "-1") {
+                                value.status = n
+                            } else if (n === "-1") {
+                                value.status = n
+                            }
+                        })
+
+                        _this.checkOneStatus({
+                            two: v,
+                            one: one,
+                            type: false
+                        })
+                    });
+                },
+                //验证保存提示
+                open:function (stype) {
+                    this.$confirm('是否保存?', '提示', {
+                        confirmButtonText: '确定',
+                        cancelButtonText: '取消',
+                        type: 'warning'
+                    }).then(() => {
+                        this.upChange(stype)
+                    }).catch(() => {
+                    });
+                },
+                //保存事件
+                upChange: function (stype) {
+                    var noTagKey = [];
+                    this.editData.filter(function (one) {
+                        if (one.title === "标的信息" || one.title === "多包信息" || one.title === "中标候选人信息") {
+                            if (allCheckFields[one.key] && one.status === "-1") {
+                                noTagKey.push(one.title);
+                            }
+                        } else {
+                            one.content.filter(function (v) {
+                                v.uInput.filter(function (u) {
+                                    if (allCheckFields[u.key] && u.status === "-1") {
+                                        noTagKey.push(u.title);
+                                    }
+                                })
+                            })
+                        }
+                    })
+                    if (noTagKey.length > 0) {
+                        var fieldText = noTagKey.join(",");
+                        fieldText = fieldText.replace(/\([^\)]*\)/g, "");
+                        this.$alert("未标注字段:" + fieldText);
+                        return
+                    }
+                    var resultStatus = false
+                    if (stype === 1) {//全部字段验证
+                        var checkAllKey = this.editData.filter(function (one) {
+                            var otherOne = one.content.filter(function (v) {
+                                return v.uInput.filter(function (u) {
+                                    return u.status === '-1'
+                                }).length
+                            })
+                            if ((one.title === "标的信息" || one.title === "多包信息" || one.title === "中标候选人信息") && (one.status === "-1")) {
+                                return true
+                            } else {
+                                return otherOne.length
+                            }
+                        })
+                        resultStatus = !Boolean(checkAllKey.length)
+                    } else {//部分字段验证
+                        var otherTag = 0 //标注状态 0:没标 1:标注成功 2:标注失败
+                        var baseTag = 0
+                        this.editData.filter(function (one) {
+                            //多包信息、中标候选人信息在为标注失败的前提下检测标注状态,一个失败不能保存
+                            if (otherTag < 2) {
+                                if (one.title === "标的信息" || one.title === "多包信息" || one.title === "中标候选人信息") {
+                                    if (one.status === "-1") {//没标
+                                        if (otherTag !== 1) {//前一个标注成功不用记录后一个是否未标
+                                            otherTag = 0
+                                        }
+                                    } else {
+                                        if (one.content.length === 0) {//不含子包
+                                            if (one.status === '2') {
+                                                otherTag = 2 //失败
+                                            } else {
+                                                otherTag = 1 //成功
+                                            }
+                                        } else {//含子包
+                                            if (one.title === "标的信息") {
+                                                var otherOne = one.content.filter(function (v) {
+                                                    if (v.status >= 1) {//子信息标注
+                                                        var twoLength = v.uInput.filter(function (u) {
+                                                            return u.status === '-1'
+                                                        })
+                                                        if (twoLength.length > 0) {
+                                                            otherTag = 2
+                                                        }
+                                                        return true //返回此条信息被标注
+                                                    }
+                                                })
+                                                if (otherTag !== 2) {
+                                                    if (otherOne.length > 0) {//
+                                                        otherTag = 1
+                                                    } else {
+                                                        otherTag = 2
+                                                    }
+                                                }
+                                            } else {
+                                                var otherOne = one.content.filter(function (v) {
+                                                    return v.uInput.filter(function (u) {
+                                                        return u.status === '-1'
+                                                    }).length
+                                                })
+                                                if (otherOne.length > 0) {//
+                                                    otherTag = 2
+                                                } else {
+                                                    otherTag = 1
+                                                }
+                                            }
+                                        }
+                                    }
+                                } else {
+                                    var baseOne = one.content.filter(function (v) {
+                                        return v.uInput.filter(function (u) {
+                                            return u.status !== '-1'
+                                        }).length
+                                    })
+                                    if (baseOne.length > 0) {//基本字段
+                                        baseTag = 1
+                                    }
+                                }
+                            }
+                        })
+                        if (otherTag === 0 && baseTag === 1) {
+                            resultStatus = true
+                        } else if (otherTag === 1) {
+                            resultStatus = true
+                        }
+                    }
+                    if (!resultStatus) {
+                        this.$alert("未标注完成");
+                        return
+                    }
+                    var d = JSON.stringify(this.editData);
+                    var _this = this
+                    $.ajax({
+                        url: "/front/data/mark",
+                        method: "post",
+                        data: {"data": d, "s_infoid": _id, "s_usertaskid": tid},
+                        success: function(res) {
+                            if (res) {
+                                _this.$message({
+                                    message: '保存成功',
+                                    type: 'success',
+                                    duration: 1000,
+                                    offset: 300
+                                });
+                                issave = true//保存成功
+                            }
+                        },
+                        error: function(err) {
+                            alert(err);
+                        }
+                    });
+                }
+                //保存提示
+                // open:function(one, type) {
+                //     this.$confirm('是否保存?', '提示', {
+                //         confirmButtonText: '确定',
+                //         cancelButtonText: '取消',
+                //         type: 'warning'
+                //     }).then(() => {
+                //         if (type) {
+                //             this.saveOneData(one)
+                //         } else {
+                //             this.upChange()
+                //         }
+                //     }).catch(() => {
+                //     });
+                // },
+                //一级保存
+                //    saveOneData: function (one) {
+                //        if (one.title==="标的信息"||one.title==="多包信息"||one.title==="中标候选人信息"){
+                //            if(one.status ===  "-1"){
+                //                this.$alert(one.title+" 未标注完成")
+                //                return
+                //            }else if (one.status !=="-1"){
+                //                var isAlert = one.content.filter(function(v) {
+                //                    return v.uInput.filter(function (u) {
+                //                        return u.status === '-1'
+                //                    }).length
+                //                })
+                //                if (isAlert.length) {
+                //                    this.$alert(one.title+" 未标注完成")
+                //                    return
+                //                }
+                //            }
+                //        }
+                //        onetext = "["+ JSON.stringify(one) +"]";
+                //        $.ajax({
+                //            url:"/center/biaozhu",
+                //            method:"post",
+                //            data: {key:onetext,_id:_id},
+                //            success:function(res){
+                //                if(res){
+                //                    document.getElementById("com-alert-val").innerHtml="保存成功";
+                //                    var label1 = document.getElementById("com-alert");
+                //                    label1.style.display="block";
+                //                    setTimeout(function(){
+                //                            label1.style.display="none";
+                //                        },
+                //                        1000)
+                //                }
+                //            },
+                //            error:function(err){
+                //                alert(err);
+                //            }
+                //        });
+                //    },
+      }
+    })
+
+    function offset(elem) {
+        if (!elem) elem = this;
+
+        var x = elem.offsetLeft;
+        var y = elem.offsetTop;
+
+        while (elem === elem.offsetParent) {
+            x += elem.offsetLeft;
+            y += elem.offsetTop;
+        }
+        return {left: x, top: y};
+    }
+</script>
+</html>

+ 2 - 3
src/web/templates/project/check_list.html → src/web/templates/project/check_task_list.html

@@ -78,7 +78,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;
@@ -111,8 +111,7 @@
                 {
                     "data": "_id", width: "11%", render: function (val, a, row, pos) {
                         tmp = '<div>' +
-                            '<a class="btn btn-sm btn-primary" href="/front/user/remark/list?pid='+row.s_projectid+'&tid=' + val + '&s_sourceinfo='+row.s_sourceinfo+'">质检</a>&nbsp;&nbsp;' +
-                            // '<a class="btn btn-sm btn-primary" onclick="deliverTask(\'' + val + '\',\''+row.s_sourceinfo+'\',\'' + row.s_status + '\')">交付</a>&nbsp;&nbsp;' +
+                            '<a class="btn btn-sm btn-primary" href="/front/user/check/data?pid='+row.s_projectid+'&tid=' + val + '&s_sourceinfo='+row.s_sourceinfo+'">质检</a>&nbsp;&nbsp;' +
                             '</div>';
                         return tmp
                     }

+ 38 - 34
src/web/templates/project/project_clear.html

@@ -37,7 +37,7 @@
                                     </div>
                                     <div class="col-xs-5 form-group">
                                         <label class="form-inline">&nbsp;操作:
-                                            <input type="button" class="btn btn-sm btn-primary" onclick="" value="标注">
+                                            <a type="button" class="btn btn-sm btn-primary" href="/front/user/jymark/list?pid={{.T.s_projectid}}&stype=all">标注</a>
                                             <input type="button" class="btn btn-sm btn-primary" onclick="dispatchTask('all')" value="分发">
                                             <input type="button" class="btn btn-sm btn-primary" value="质检">
                                             <input type="button" class="btn btn-sm btn-primary" value="质检结果">
@@ -57,7 +57,7 @@
                                     </div>
                                     <div class="col-xs-5 form-group">
                                         <label class="form-inline">操作:
-                                            <input type="button" class="btn btn-sm btn-primary" onclick="" value="标注">
+                                            <a type="button" class="btn btn-sm btn-primary" href="/front/user/jymark/list?pid={{.T.s_projectid}}&stype=notag">标注</a>
                                             <input type="button" class="btn btn-sm btn-primary" onclick="dispatchTask('notag')" value="分发">
                                             <input type="button" class="btn btn-sm btn-primary" value="质检">
                                             <input type="button" class="btn btn-sm btn-primary" value="质检结果">
@@ -77,7 +77,7 @@
                                     </div>
                                     <div class="col-xs-5 form-group">
                                         <label class="form-inline">操作:
-                                            <a type="button" class="btn btn-sm btn-primary" href="">标注</a>
+                                            <a type="button" class="btn btn-sm btn-primary" href="/front/user/jymark/list?pid={{.T.s_projectid}}&stype=tag">标注</a>
                                             <input type="button" class="btn btn-sm btn-primary" onclick="dispatchTask('tag')" value="分发">
                                             <input type="button" class="btn btn-sm btn-primary" value="质检">
                                             <input type="button" class="btn btn-sm btn-primary" value="质检结果">
@@ -202,7 +202,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;
@@ -391,42 +391,46 @@
 
     // 收回
     function retrieveTask(id, sourceinfo, status,givenum) {
-        if (status === "未开始" || status === "进行中") {
-            $.ajax({
-                url: "/front/project/task/retrieve",
-                type: 'POST',
-                data: { "s_sourceinfo": sourceinfo, "taskid": id, "s_status": status,"i_givenum" :givenum},
-                success: function (r) {
-                    if (r.success) {
-                        location.reload()
-                    } else {
-                        showTip(r.msg);
+        showConfirm("确认要收回当前任务吗?", function () {
+            if (status === "未开始" || status === "进行中") {
+                $.ajax({
+                    url: "/front/project/task/retrieve",
+                    type: 'POST',
+                    data: { "s_sourceinfo": sourceinfo, "taskid": id, "s_status": status,"i_givenum" :givenum},
+                    success: function (r) {
+                        if (r.success) {
+                            location.reload()
+                        } else {
+                            showTip(r.msg);
+                        }
                     }
-                }
-            })
-        }else {
-            showTip("操作不允许")
-        }
+                })
+            }else {
+                showTip("操作不允许")
+            }
+        })
     }
 
     // 打回
     function repulseTask(id, sourceinfo,status) {
-        if (status === "已完成") {
-            $.ajax({
-                url: "/front/project/task/repulse",
-                type: 'POST',
-                data: {"s_sourceinfo": sourceinfo, "taskid": id, "s_tatus": status},
-                success: function (r) {
-                    if (r.success) {
-                        location.reload()
-                    } else {
-                        showTip(r.msg);
+        showConfirm("确认要打回当前任务吗?", function () {
+            if (status === "已完成") {
+                $.ajax({
+                    url: "/front/project/task/repulse",
+                    type: 'POST',
+                    data: {"s_sourceinfo": sourceinfo, "taskid": id, "s_tatus": status},
+                    success: function (r) {
+                        if (r.success) {
+                            location.reload()
+                        } else {
+                            showTip(r.msg);
+                        }
                     }
-                }
-            })
-        }else {
-            showTip("操作不允许")
-        }
+                })
+            }else {
+                showTip("操作不允许")
+            }
+        })
     }
 
     function closeTask(id, sourceinfo,status) {

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

@@ -260,7 +260,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;

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

@@ -1386,7 +1386,7 @@
                     $.ajax({
                         url: "/front/data/mark",
                         method: "post",
-                        data: {"data": d, "s_infoid": _id, "s_usertaskid": tid},
+                        data: {"data": d, "s_infoid": _id, "s_usertaskid": {{ .T.tid}}},
                         success: function (res) {
                             if (res) {
                                 _this.$message({

+ 93 - 19
src/web/templates/project/remark_jy_list.html

@@ -9,23 +9,45 @@
             <small></small>
         </h1>
         <ol class="breadcrumb">
-            <li><a href="/front/user/task/list"><i class="fa fa-dashboard"></i> 任务列表</a></li>
+            <li><a href="/front/project"><i class="fa fa-dashboard"></i> 项目列表</a></li>
+            <li><a href="/front/project/task/list?pid={{ .T.pid }}"><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="col-xs-12">
-                <div class="box">
+            <div class="box">
                     <div class="box-body">
-                        <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=-1>全部</option>
-                                    <option value=0>未标注</option>
-                                    <option value=1>已标注</option>
+                        <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">
+<!--                                <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()">
+                            </label>
                         </div>
                         <table id="dataTable" class="table table-bordered table-hover">
                             <thead>
@@ -38,7 +60,6 @@
                         </table>
                     </div>
                 </div>
-            </div>
         </div>
     </section>
 </div>
@@ -47,23 +68,25 @@
 <script>
     menuActive("/front/user/task/list");
 
-    let tid = {{ .T.tid }}
     let pid = {{ .T.pid }}
+    let stype = {{ .T.stype }}
     let sourceinfo = {{ .T.s_sourceinfo }}
+    let topsubtype = {{ .T.topsubtype }}
+    let allfield = {{ .T.allfield }}
 
     $(function () {
         ttable = $('#dataTable').dataTable({
             "paging": true,
             "lengthChange": false,
-            "searching": true,
+            "searching": false,
             "ordering": false,
             "info": true,
             "autoWidth": false,
             "serverSide": true,
             "ajax": {
-                "url": "/front/user/remark/list",
+                "url": "",
                 "type": "post",
-                "data": {"tid": tid, "s_sourceinfo": sourceinfo}
+                "data": {"pid": pid, "s_sourceinfo": sourceinfo, "stype": stype}
             },
             "language": {
                 "url": "/dist/js/dataTables.chinese.lang"
@@ -75,7 +98,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;
@@ -95,9 +118,9 @@
                 {"data": "v_baseinfo.title", render: function (val, index, row) {
                         let tmp;
                         if (row["b_istag"]) {
-                            tmp = '<a style="display: inline-block;cursor:pointer;font-size:16px;color: green" target="_blank" href="/front/user/remark/detail/?pid='+pid+'&tid=' + tid +'&did=' + row._id + '&s_sourceinfo='+sourceinfo+'">' + val + '</a>'
+                            tmp = '<a style="display: inline-block;cursor:pointer;font-size:16px;color: green" target="_blank" href="/front/user/remark/detail/?pid='+pid+'&did=' + row._id + '&s_sourceinfo='+sourceinfo+'">' + val + '</a>'
                         } else {
-                            tmp = '<a style="display: inline-block;cursor:pointer;font-size:16px;color: #428bca" target="_blank" href="/front/user/remark/detail/?pid='+pid+'&tid=' + tid +'&did=' + row._id + '&s_sourceinfo='+sourceinfo+'">' + val + '</a>'
+                            tmp = '<a style="display: inline-block;cursor:pointer;font-size:16px;color: #428bca" target="_blank" href="/front/user/remark/detail/?pid='+pid+'&did=' + row._id + '&s_sourceinfo='+sourceinfo+'">' + val + '</a>'
                         }
                         return tmp
                     }}
@@ -106,12 +129,63 @@
                 $("#dataTable_filter").append($('#status-div'))
             },
             "fnServerParams": function (e) {
-                e.i_ckdata = $("#statusSelect option:selected").val()
+                e.datatype = $("#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()
+                    }
+                }
             }
         });
-        $('#statusSelect').on('changed.bs.select', function () {
+
+        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");
+
+        $('#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()
+            console.log(v, v !== "-1")
+            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 searchBtn() {
+        ttable.api().ajax.reload();
+    }
+
 </script>

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

@@ -75,7 +75,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;

+ 18 - 16
src/web/templates/project/task_detail.html

@@ -172,7 +172,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;
@@ -407,22 +407,24 @@
 
     // 收回
     function retrieveTask(id, sourceinfo, status) {
-        if (status === "未开始" || status === "进行中") {
-            $.ajax({
-                url: "/front/user/task/retrieve",
-                type: 'POST',
-                data: {"s_sourceinfo": sourceinfo, "taskid": id, "s_status": status},
-                success: function (r) {
-                    if (r.success) {
-                        location.reload()
-                    } else {
-                        showTip(r.msg);
+        showConfirm("确认要收回当前任务吗?", function () {
+            if (status === "未开始" || status === "进行中") {
+                $.ajax({
+                    url: "/front/user/task/retrieve",
+                    type: 'POST',
+                    data: {"s_sourceinfo": sourceinfo, "taskid": id, "s_status": status},
+                    success: function (r) {
+                        if (r.success) {
+                            location.reload()
+                        } else {
+                            showTip(r.msg);
+                        }
                     }
-                }
-            })
-        }else {
-            showTip("操作不允许")
-        }
+                })
+            }else {
+                showTip("操作不允许")
+            }
+        })
     }
     function closeTask(id, status, sourceinfo) {
         if (status === "未开始") {

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

@@ -79,7 +79,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;

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

@@ -99,7 +99,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;

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

@@ -78,7 +78,7 @@
                     if ($("#changePage").val() && $("#changePage").val() > 0) {
                         var redirectpage = $("#changePage").val() - 1;
                     }
-                    ttable.page(redirectpage).draw(false);
+                    ttable.api().page(redirectpage).draw(false);
                 });
                 this.api().column(0).nodes().each(function (cell, i) {
                     cell.innerHTML = i + 1;