Jianghan 3 年 前
コミット
7544f8241e

+ 6 - 4
exportData/config.json

@@ -1,14 +1,16 @@
 {
-  "mgoAddr": "192.168.3.166:27082",
-  "mgoDbName": "shanghaitf",
-  "mgoColl": "20220316Shdx_zhong_3_2_qx",
+  "mgoAddr": "192.168.3.207:27092",
+  "mgoDbName": "wjh",
+  "mgoColl": "bidding",
   "mgoSize": 10,
-  "exportType": 2,
+  "exportType": 3,
   "isMark": 1,
   "search": {},
   "fieldsSort": ["matchkey", "area", "city", "title", "subtype", "detail", "publishtime", "href", "jybxhref", "projectname",
     "projectcode", "projectscope", "budget", "bidamount", "bidopentime", "buyer", "buyerperson", "buyertel", "agency", "s_winner",
     "winnerperson", "winnertel", "company_phone", "company_email", "id"],
+  "fields_purchase": [ "area", "city", "title", "subtype", "detail", "publishtime", "href", "jybxhref", "projectname",
+    "projectcode", "projectscope", "id"],
   "fields": {
     "matchkey": "信息匹配词",
     "area": "省份",

+ 92 - 10
exportData/main.go

@@ -17,6 +17,7 @@ var (
 	Search             map[string]interface{}
 	Fields             map[string]interface{}
 	FieldsArr          []string
+	FiedlsPurchase     []string
 	SE                 = util.SimpleEncrypt{Key: "topJYBX2019"}
 )
 
@@ -36,6 +37,7 @@ func init() {
 	Search = Sysconfig["search"].(map[string]interface{})
 	FieldsArr = util.ObjArrToStringArr(Sysconfig["fieldsSort"].([]interface{}))
 	Fields = Sysconfig["fields"].(map[string]interface{})
+	FiedlsPurchase = util.ObjArrToStringArr(Sysconfig["fields_purchase"].([]interface{}))
 
 	if ExportType == 1 {
 		FieldsArr[len(FieldsArr)-1] = "itemname"
@@ -47,6 +49,16 @@ func init() {
 		Fields["unitprice"] = "单价"
 		Fields["number"] = "数量"
 		Fields["totalprice"] = "小计"
+	} else if ExportType == 3 {
+		FiedlsPurchase[len(FiedlsPurchase)-1] = "projectname_purchase"
+		FiedlsPurchase = append(FiedlsPurchase, "projectscope_purchase", "item", "buyer_purchase", "totalprice", "expurasingtime", "cgyxxqhref", "id")
+		Fields["projectname_purchase"] = "采购意向名称"
+		Fields["projectscope_purchase"] = "采购内容"
+		Fields["item"] = "采购品目"
+		Fields["buyer_purchase"] = "采购单位"
+		Fields["totalprice"] = "预计采购金额(元)"
+		Fields["expurasingtime"] = "预计采购时间"
+		Fields["cgyxxqhref"] = "采购意向详情链接"
 	}
 	util.Debug(FieldsArr)
 }
@@ -62,8 +74,15 @@ func main() {
 		panic(err)
 	}
 	row := sheet.AddRow()
-	for _, v := range FieldsArr {
-		row.AddCell().SetValue(Fields[v])
+	if ExportType == 3 {
+		// 标的物 采购意向
+		for _, v := range FiedlsPurchase {
+			row.AddCell().SetValue(Fields[v])
+		}
+	} else {
+		for _, v := range FieldsArr {
+			row.AddCell().SetValue(Fields[v])
+		}
 	}
 
 	q := map[string]interface{}{}
@@ -81,10 +100,17 @@ func main() {
 		if count%500 == 0 {
 			util.Debug("current ---", count)
 		}
-		baseInfo := tmp["v_baseinfo"].(map[string]interface{})
-		tagInfo := tmp["v_taginfo"].(map[string]interface{})
+		var baseInfo map[string]interface{}
+		if tmp["v_baseinfo"] != nil {
+			baseInfo = tmp["v_baseinfo"].(map[string]interface{})
+		} else {
+			baseInfo = tmp
+		}
+		tagInfo, _ := tmp["v_taginfo"].(map[string]interface{})
 
-		if ExportType == 0 {
+		switch ExportType {
+		case 0:
+			// 不拆分
 			row := sheet.AddRow()
 			for _, v := range FieldsArr {
 				if v == "publishtime" || v == "bidopentime" || v == "project_startdate" || v == "project_completedate" ||
@@ -102,7 +128,7 @@ func main() {
 					row.AddCell().SetValue(baseInfo[v])
 				}
 			}
-		} else if ExportType == 1 {
+		case 1:
 			// 拆分标的物
 			if IsMark == 1 {
 				if tagInfo["purchasinglist"] != nil {
@@ -183,9 +209,8 @@ func main() {
 				util.Debug("是否标注isMark字段值有问题~", IsMark)
 				break
 			}
-		} else if ExportType == 2 {
-			//if IsMark == 1 {
-			//}
+		case 2:
+			// 多包拆分
 			if baseInfo["package"] != nil {
 				pkg := baseInfo["package"].(map[string]interface{})
 				for _, p := range pkg {
@@ -248,8 +273,65 @@ func main() {
 					}
 				}
 			}
+		case 3:
+			// 标的物 采购意向数据拆分
+			if baseInfo["purchasinglist"] != nil {
+				plist := baseInfo["purchasinglist"].([]interface{})
+				for _, p := range plist {
+					row := sheet.AddRow()
+					m := make(map[string]interface{})
+					p1 := p.(map[string]interface{})
+					for _, v := range FiedlsPurchase {
+						if v == "projectname_purchase" || v == "projectscope_purchase" || v == "item" || v == "buyer_purchase" ||
+							v == "totalprice" || v == "expurasingtime" || v == "cgyxxqhref" {
+							v1 := strings.ReplaceAll(v, "_purchase", "")
+							row.AddCell().SetValue(p1[v1])
+							m[v] = p1[v1]
+						} else if v == "publishtime" || v == "bidopentime" || v == "project_startdate" || v == "project_completedate" ||
+							v == "signaturedate" || v == "comeintime" || v == "createtime" {
+							str := ""
+							if baseInfo[v] != nil {
+								date := util.Int64All(baseInfo[v])
+								str = util.FormatDateByInt64(&date, util.Date_Short_Layout)
+							}
+							row.AddCell().SetValue(str)
+							m[v] = str
+						} else if v == "id" {
+							id := SE.EncodeString(mongodb.BsonIdToSId(tmp["_id"]))
+							row.AddCell().SetValue(id)
+							m[v] = id
+						} else {
+							row.AddCell().SetValue(baseInfo[v])
+							m[v] = baseInfo[v]
+						}
+					}
+					Mgo.Save("bidding_v1", m)
+				}
+			} else {
+				row := sheet.AddRow()
+				m := make(map[string]interface{})
+				for _, v := range FiedlsPurchase {
+					if v == "publishtime" || v == "bidopentime" || v == "project_startdate" || v == "project_completedate" ||
+						v == "signaturedate" || v == "comeintime" || v == "createtime" {
+						str := ""
+						if baseInfo[v] != nil {
+							date := util.Int64All(baseInfo[v])
+							str = util.FormatDateByInt64(&date, util.Date_Short_Layout)
+						}
+						row.AddCell().SetValue(str)
+						m[v] = str
+					} else if v == "id" {
+						id := SE.EncodeString(mongodb.BsonIdToSId(tmp["_id"]))
+						row.AddCell().SetValue(id)
+						m[v] = id
+					} else {
+						row.AddCell().SetValue(baseInfo[v])
+						m[v] = baseInfo[v]
+					}
+				}
+				Mgo.Save("bidding_v1", m)
+			}
 		}
-
 	}
 	util.Debug("over ---", count)
 	fname := fmt.Sprintf("./数据导出%s.xlsx", util.NowFormat(util.DATEFORMAT))

+ 10 - 6
src/front/front.go

@@ -83,11 +83,15 @@ type Front struct {
 	userTaskClose    xweb.Mapper `xweb:"/front/user/task/close"`    //用户任务关闭改打回
 
 	//group task
-	groupTaskListByAdmin xweb.Mapper `xweb:"/front/group/admin/task/list"` //用户组任务列表(系统管理员权限)
-	groupTaskListByGroup xweb.Mapper `xweb:"/front/group/task/list"`       //用户组任务列表(用户组权限)
-	groupTaskDeliver     xweb.Mapper `xweb:"/front/group/task/deliver"`    //用户组任务交付
-	groupTaskExport      xweb.Mapper `xweb:"/front/group/task/export"`     //用户组任务导出
-	groupUserTaskList    xweb.Mapper `xweb:"/front/group/user/task/list"`  //用户组下用户任务列表
+	groupTaskListByAdmin xweb.Mapper `xweb:"/front/group/admin/task/list"`   //用户组任务列表(系统管理员权限)
+	groupTaskListByGroup xweb.Mapper `xweb:"/front/group/task/list"`         //用户组任务列表(用户组权限)
+	groupTaskDeliver     xweb.Mapper `xweb:"/front/group/task/deliver"`      //用户组任务交付
+	groupTaskExport      xweb.Mapper `xweb:"/front/group/task/export"`       //用户组任务导出
+	groupUserTaskList    xweb.Mapper `xweb:"/front/group/user/task/list"`    //用户组下用户任务列表
+	groupStatsTask       xweb.Mapper `xweb:"/front/group/task/stats"`        //剑鱼任务组统计
+	groupStatsTaskExport xweb.Mapper `xweb:"/front/group/task/stats/export"` //剑鱼任务组统计任务导出
+
+	checkResultWb xweb.Mapper `xweb:"/front/group/check/wb/result"` //外包质检结果
 
 	//mark
 	dataMark       xweb.Mapper `xweb:"/front/data/mark"`        //数据标注
@@ -169,7 +173,7 @@ func (f *Front) UpdatePwd() {
 	password := f.GetString("pwd")
 	set := map[string]interface{}{
 		"$set": map[string]interface{}{
-			"s_pwd": qu.SE.EncodeString(password),
+			"s_password": qu.SE.EncodeString(password),
 		},
 	}
 	if Mgo.UpdateById("s_user", id, set) {

+ 365 - 1
src/front/group.go

@@ -1,12 +1,14 @@
 package front
 
 import (
+	"encoding/json"
 	"fmt"
 	"github.com/shopspring/decimal"
 	"github.com/tealeg/xlsx"
 	"mongodb"
 	"os"
 	qu "qfw/util"
+	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -34,6 +36,10 @@ func (f *Front) GroupTaskListByGroup() {
 		}
 		if status != "-1" { //任务状态
 			query["s_status"] = status
+		} else {
+			query["s_status"] = map[string]interface{}{
+				"$in": []string{"未开始", "进行中", "已完成"},
+			}
 		}
 		if search != "" {
 			query["$or"] = []interface{}{
@@ -100,6 +106,10 @@ func (f *Front) GroupTaskListByAdmin() {
 		}
 		if status != "-1" { //任务状态
 			query["s_status"] = status
+		} else {
+			query["s_status"] = map[string]interface{}{
+				"$in": []string{"未开始", "进行中", "已完成"},
+			}
 		}
 		if search != "" {
 			query["$or"] = []interface{}{
@@ -258,9 +268,18 @@ func (f *Front) GroupTaskDeliver() {
 	} else {
 		msg = "查询任务失败"
 	}
-	// 项目下的数据全部完成,项目中打上标记b_iscomplete
+
 	sourinfo := qu.ObjToString((*groupTask)["s_sourceinfo"])
 	pid := qu.ObjToString((*groupTask)["s_projectid"])
+	// 组任务交付 默认保存质检统计结果
+	mp := make(map[string]interface{})
+	mp["s_username"] = username
+	mp["s_taskid"] = groupTaskId
+	mp["i_createtime"] = time.Now().Unix()
+	checkStat(sourinfo, groupTaskId, pid, mp)
+	util.Mgo.Save("f_check_result", mp)
+
+	// 项目下的数据全部完成,项目中打上标记b_iscomplete
 	info, _ := util.Mgo.FindOneByField(sourinfo, map[string]interface{}{"b_istag": false}, map[string]interface{}{"s_status": 1})
 	if len(*info) == 0 {
 		util.Mgo.UpdateById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"$set": map[string]interface{}{"b_iscomplete": true}})
@@ -268,6 +287,140 @@ func (f *Front) GroupTaskDeliver() {
 	f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
 }
 
+func checkStat(sourceinfo, groupTaskId, pid string, mp map[string]interface{}) {
+	sess := util.Mgo.GetMgoConn()
+	defer util.Mgo.DestoryMongoConn(sess)
+
+	var allNum int
+	markNum, checkNum, checkNumR := 0, 0, 0 // 标注数量,	审核数据量,	审核数据完全正确的数据量
+	cmaps := make(map[string]int)           // 标注字段整体准确率
+	umaps := make(map[string]interface{})   // 按人员 字段准确率
+
+	task, _ := util.Mgo.FindById(util.TASKCOLLNAME, groupTaskId, map[string]interface{}{"i_givenum": 1})
+	allNum = qu.IntAll((*task)["i_givenum"])
+	projcet, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"v_fields": 1})
+
+	query := map[string]interface{}{"s_grouptaskid": groupTaskId}
+	result := sess.DB(util.Mgo.DbName).C(sourceinfo).Find(query).Iter()
+
+	fields := (*projcet)["v_fields"].(map[string]interface{})
+	purchasingTag := false // 标的物统计标识
+	var strs []string
+	if fields["purchasinglist"] != nil {
+		purchasingTag = true
+		delete(fields, "purchasinglist")
+	}
+	for k := range fields {
+		strs = append(strs, k)
+	}
+	pNum, pEffNum := 0, 0               // 标的物数量, 标的物有效数量
+	fieldNumMap := make(map[string]int) //字段总标注量,
+	tagNumMap := make(map[string]int)   //字段标注数据量(标的物有效)
+	rightNumMap := make(map[string]int) //正确数据(标的物有效)
+	for tmp := make(map[string]interface{}); result.Next(&tmp); markNum++ {
+		user := qu.ObjToString(tmp["s_login"])
+		var up map[string]int
+		if umaps[user] == nil {
+			up = make(map[string]int)
+		} else {
+			up = umaps[user].(map[string]int)
+		}
+		up["ck_count"] += 1
+		umaps[user] = up
+		if tmp["b_check"].(bool) {
+			if f, ok := tmp["v_checkinfo"].(map[string]interface{}); ok {
+				flag := true // 数据整体准确率
+				// 按人员统计字段准备率
+				var up map[string]int
+				if umaps[user] == nil {
+					up = make(map[string]int)
+				} else {
+					up = umaps[user].(map[string]int)
+				}
+				for k1 := range cmaps {
+					if qu.IntAll(f[k1]) == 1 {
+						cmaps[k1] += 1 // 字段整体正确率
+						up[k1] += 1
+					} else {
+						flag = false
+					}
+				}
+				up["re_count"] += 1
+				umaps[user] = up
+				if flag {
+					checkNumR++
+					up["re_rg_count"] += 1
+				}
+			}
+		}
+		if tmp["b_check"].(bool) && purchasingTag {
+			info := tmp["v_baseinfo"].(map[string]interface{})
+			checkInfo := tmp["v_checkinfo"].(map[string]interface{})
+			if pList, o := info["purchasinglist"].([]interface{}); o {
+				pNum += len(pList)
+				if tmp["b_isEff"].(bool) {
+					pEffNum += 1
+				}
+				for _, p := range pList {
+					p1 := p.(map[string]interface{})
+					for f := range purchasingField {
+						if qu.ObjToString(p1[f]) != "" {
+							fieldNumMap[f] += 1
+							if b, o := p1["b_isEff"].(bool); b && o {
+								tagNumMap[f] += 1
+							}
+						}
+					}
+				}
+			}
+			if cList, o := checkInfo["purchasinglist"].([]interface{}); o {
+				for _, c := range cList {
+					c1 := c.(map[string]interface{})
+					for f := range purchasingField {
+
+						if qu.IntAll(c1[f]) == 1 {
+							rightNumMap[f] += 1
+						}
+					}
+				}
+			}
+		}
+	}
+	qu.Debug(cmaps)
+	qu.Debug(umaps)
+	pResult := method(fieldNumMap, tagNumMap, rightNumMap)
+	var userSelect []string
+	var dataSelect []map[string]interface{}
+	userSelect = append(userSelect, "全部")
+	tmp := make(map[string]interface{})
+	tmp["name"] = "全部"
+	tmp["num1"] = allNum
+	tmp["num2"] = checkNum
+	tmp["num3"] = checkNumR
+	tmp["num4"] = CountPr(checkNumR, checkNum)
+	dataSelect = append(dataSelect, tmp)
+
+	sort.Strings(strs)
+	for _, v := range strs {
+		tmp1 := make(map[string]interface{})
+		tmp1["name"] = fields[v]
+		tmp1["num1"] = markNum
+		tmp1["num2"] = checkNum
+		tmp1["num3"] = cmaps[v]
+		tmp1["num4"] = CountPr(cmaps[v], checkNum)
+		dataSelect = append(dataSelect, tmp1)
+	}
+	qu.Debug("字段统计---", dataSelect)
+	qu.Debug("字段统计---", pResult)
+	mp["taskNum"] = allNum
+	mp["v_result"] = dataSelect
+	mp["v_purchasing"] = pResult
+	mp["taskCheckNum"] = checkNum
+	mp["taskCheckRight"] = checkNumR
+	mp["pNum"] = pNum
+	mp["pEffNum"] = pEffNum
+}
+
 var modelpath string = "web/model/任务详情%d.xlsx"
 
 // GroupTaskExport 用户组任务导出
@@ -371,3 +524,214 @@ func (f *Front) GroupTaskExport() {
 		f.ServeJson("没有数据")
 	}
 }
+
+func (f *Front) GroupStatsTask() {
+	defer qu.Catch()
+	starttime, _ := f.GetInt("i_starttime")
+	completetime, _ := f.GetInt("i_completetime")
+	status := f.GetString("s_status")
+	searchStr := f.GetString("s_search")
+	search := strings.TrimSpace(searchStr)
+	query := map[string]interface{}{
+		"s_stype": "group",
+	}
+	if status != "-1" { //任务状态
+		query["s_status"] = status
+	}
+	if search != "" {
+		query["$or"] = []interface{}{
+			map[string]interface{}{"s_entname": map[string]interface{}{"$regex": search}},
+		}
+	}
+	if starttime > 0 {
+		query["i_starttime"] = map[string]interface{}{
+			"$gte": starttime,
+		}
+	}
+	if completetime > 0 {
+		query["i_completetime"] = map[string]interface{}{
+			"$lte": completetime,
+		}
+	}
+	qu.Debug("Query:", query)
+	count := util.Mgo.Count(util.TASKCOLLNAME, query)
+	if count > 0 {
+		var ArrMap []map[string]interface{}
+		list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, nil, nil, false, -1, -1)
+		for i := 0; i < len(*list); i++ {
+			if i == 0 {
+				m, _ := Method(nil, (*list)[i])
+				ArrMap = append(ArrMap, m)
+			} else {
+				m, b := Method((*list)[i-1], (*list)[i])
+				if b {
+					ArrMap = ArrMap[:len(ArrMap)-1] // 删除最后一个
+					ArrMap = append(ArrMap, m)
+				} else {
+					ArrMap = append(ArrMap, m)
+				}
+			}
+		}
+		f.T["datasource"] = ArrMap
+
+	}
+	_ = f.Render("project/task_list_stats.html")
+}
+
+func (f *Front) GroupStatsTaskExport() {
+	var data []map[string]interface{}
+	dataStr := f.GetString("param")
+	err := json.Unmarshal([]byte(dataStr), &data)
+	if err != nil {
+		qu.Debug("Json Unmarshal Error")
+		f.ServeJson(map[string]interface{}{"success": false, "msg": "解析数据失败"})
+		return
+	}
+	file, err := xlsx.OpenFile("web/model/taskstatsmodel.xlsx")
+	if err != nil {
+		qu.Debug("Load Excel Model Error")
+		f.ServeJson(map[string]interface{}{"success": false, "msg": "加载脚本失败"})
+		return
+	}
+	sheet := file.Sheets[0]
+	for _, l := range data {
+		row := sheet.AddRow()
+		projectname := qu.ObjToString(l["s_projectname"])
+		groupname := qu.ObjToString(l["s_groupname"])
+		datatype := qu.ObjToString(l["s_datatype"])
+		num := qu.IntAll(l["num"])
+		row.AddCell().SetValue(projectname)
+		row.AddCell().SetValue(groupname)
+		row.AddCell().SetValue(datatype)
+		row.AddCell().SetValue(num)
+	}
+	fname := fmt.Sprintf("%d.xlsx", time.Now().Unix())
+	qu.Debug("File Name:", fname)
+	err = file.Save(fname)
+	if err != nil {
+		qu.Debug("Save Excel" + fname + "Error")
+		f.ServeJson(map[string]interface{}{"success": false, "msg": "文件保存失败"})
+		return
+	}
+	arr := strings.Split(fname, "/")
+	f.ResponseWriter.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", arr[len(arr)-1]))
+	f.ServeFile(fname)
+	go func(path string) {
+		time.Sleep(time.Second * 30)
+		os.Remove(path)
+	}(fname)
+	f.ServeJson(map[string]interface{}{"success": true})
+}
+
+func Method(lastTmp, tmp map[string]interface{}) (map[string]interface{}, bool) {
+	if qu.ObjToString(tmp["s_datatype"]) == "招标公告" || qu.ObjToString(tmp["s_datatype"]) == "中标公告" {
+		if lastTmp == nil {
+			m := make(map[string]interface{})
+			m["s_projectid"] = tmp["s_projectid"]
+			m["s_projectname"] = tmp["s_projectname"]
+			m["s_groupname"] = tmp["s_groupname"]
+			m["s_datatype"] = tmp["s_datatype"]
+			m["num"] = tmp["i_givenum"]
+			return m, true
+		} else {
+			if qu.ObjToString(lastTmp["s_projectid"]) == qu.ObjToString(tmp["s_projectid"]) &&
+				qu.ObjToString(lastTmp["s_groupname"]) == qu.ObjToString(tmp["s_groupname"]) {
+				lastTmp["num"] = qu.IntAll(lastTmp["num"]) + qu.IntAll(tmp["num"])
+				return lastTmp, false
+			} else {
+				m := make(map[string]interface{})
+				m["s_projectid"] = tmp["s_projectid"]
+				m["s_projectname"] = tmp["s_projectname"]
+				m["s_groupname"] = tmp["s_groupname"]
+				m["s_datatype"] = tmp["s_datatype"]
+				m["num"] = tmp["i_givenum"]
+				return m, true
+			}
+		}
+	} else {
+		// 标的物统计
+		if lastTmp == nil {
+			m := make(map[string]interface{})
+			m["s_projectid"] = tmp["s_projectid"]
+			m["s_projectname"] = tmp["s_projectname"]
+			m["s_groupname"] = tmp["s_groupname"]
+			m["s_datatype"] = tmp["s_datatype"]
+			m["num"] = Method1(tmp)
+			return m, true
+		} else {
+			if qu.ObjToString(lastTmp["s_projectid"]) == qu.ObjToString(tmp["s_projectid"]) &&
+				qu.ObjToString(lastTmp["s_groupname"]) == qu.ObjToString(tmp["s_groupname"]) {
+				lastTmp["num"] = qu.IntAll(lastTmp["num"]) + Method1(tmp)
+				return lastTmp, false
+			} else {
+				m := make(map[string]interface{})
+				m["s_projectid"] = tmp["s_projectid"]
+				m["s_projectname"] = tmp["s_projectname"]
+				m["s_groupname"] = tmp["s_groupname"]
+				m["s_datatype"] = tmp["s_datatype"]
+				m["num"] = Method1(tmp)
+				return m, true
+			}
+		}
+	}
+}
+
+func Method1(tmp map[string]interface{}) int {
+	id := mongodb.BsonIdToSId(tmp["_id"])
+	sourceinfo := qu.ObjToString(tmp["s_sourceinfo"])
+	query := map[string]interface{}{"s_groupid": id, "b_isEff": true}
+	data, _ := util.Mgo.Find(sourceinfo, query, nil, `{"v_baseinfo": 1}`, false, -1, -1)
+	if len(*data) > 0 {
+		count := 0
+		for _, m := range *data {
+			if m1, o := m["v_baseinfo"].(map[string]interface{}); o {
+				if m2, o1 := m1["purchasinglist"].([]interface{}); o1 {
+					for _, m3 := range qu.ObjArrToMapArr(m2) {
+						if m3["b_isEff"].(bool) {
+							count++
+						}
+					}
+				}
+			}
+		}
+		return count
+	}
+	return 0
+}
+
+func (f *Front) CheckResultWb() {
+	defer qu.Catch()
+	pid := f.GetString("pid")
+	tid := f.GetString("tid")
+	sourceinfo := f.GetString("s_sourceinfo")
+	if f.Method() == "POST" {
+		query := map[string]interface{}{"s_taskid": tid}
+		info, _ := util.Mgo.FindOne("f_check_result", query)
+		if len(*info) > 0 {
+			f.ServeJson(map[string]interface{}{"success": true})
+		} else {
+			f.ServeJson(map[string]interface{}{"success": false, "msg": "用户组任务未交付"})
+		}
+	} else {
+		query := map[string]interface{}{"s_taskid": tid}
+		info, _ := util.Mgo.FindOne("f_check_result", query)
+
+		var userSelect []string
+		userSelect = append(userSelect, "全部")
+
+		f.T["pid"] = pid
+		f.T["tid"] = tid
+		f.T["sourceinfo"] = sourceinfo
+		f.T["taskNum"] = (*info)["taskNum"]
+		f.T["taskTagNum"] = (*info)["taskNum"]
+		f.T["taskCheckNum"] = (*info)["taskCheckNum"]
+		f.T["taskCheckRight"] = (*info)["taskCheckRight"]
+		f.T["pNum"] = (*info)["pNum"]       // 标的物数量
+		f.T["pEffNum"] = (*info)["pEffNum"] //标的物有效数据量
+		f.T["tableData"] = map[string]interface{}{"全部": (*info)["v_result"]}
+		f.T["pResult"] = (*info)["v_purchasing"]
+		f.T["userSelect"] = userSelect
+		_ = f.Render("project/check_result.html", &f.T)
+	}
+
+}

+ 24 - 10
src/front/project.go

@@ -45,6 +45,10 @@ func (f *Front) ProjectList() {
 		query := map[string]interface{}{}
 		if status != "-1" {
 			query["s_status"] = status
+		} else {
+			query["s_status"] = map[string]interface{}{
+				"$in": []string{"未开始", "进行中", "已完成"},
+			}
 		}
 		if search != "" {
 			query["$or"] = []interface{}{
@@ -58,9 +62,7 @@ func (f *Front) ProjectList() {
 		count := util.Mgo.Count(util.PROJECTCOLLNAME, query)
 		f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
 	} else {
-		query := map[string]interface{}{"s_type": "tag"}
-		info, _ := util.Mgo.Find("v_field", query, nil, map[string]interface{}{"s_name": 1, "s_code": 1}, false, -1, -1)
-		f.T["fields"] = *info
+		f.T["fields"] = util.FieldsMap
 		f.T["dataTypeArr"] = util.DataTypeArr
 		f.T["dataTypeMap"] = util.DataTypeMap
 		_ = f.Render("project/project_list.html", &f.T)
@@ -156,9 +158,8 @@ func (f *Front) ProjectSave() {
 		s_personname := f.GetString("s_personname")
 		s_datatype := f.GetString("s_datatype") //数据类型
 		fields := f.GetString("v_fields_diy")
-		fieldsAll := f.GetString("v_fields")
+		//fieldsAll := f.GetString("v_fields")
 		qu.Debug(fields)
-		qu.Debug(fieldsAll)
 		v_fields := map[string]interface{}{}
 		v_fieldsAll := map[string]interface{}{}
 		if err := json.Unmarshal([]byte(fields), &v_fields); err != nil {
@@ -166,12 +167,21 @@ func (f *Front) ProjectSave() {
 			f.ServeJson(map[string]interface{}{"success": false, "msg": err})
 			return
 		}
-		if err := json.Unmarshal([]byte(fieldsAll), &v_fieldsAll); err != nil {
-			qu.Debug("v_FieldsAll Unmarshal Failed:", err)
-			f.ServeJson(map[string]interface{}{"success": false, "msg": err})
-			return
+		//if err := json.Unmarshal([]byte(fieldsAll), &v_fieldsAll); err != nil {
+		//	qu.Debug("v_FieldsAll Unmarshal Failed:", err)
+		//	f.ServeJson(map[string]interface{}{"success": false, "msg": err})
+		//	return
+		//}
+		for s, v := range v_fields {
+			v_fieldsAll[s] = v
+		}
+		for _, v := range qu.ObjArrToStringArr(util.DataTypeMap[s_datatype].([]interface{})) {
+			if strings.Contains(v, "purchasinglist") {
+				v_fieldsAll["purchasinglist"] = util.FieldsMap["purchasinglist"]
+			} else {
+				v_fieldsAll[v] = util.FieldsMap[v]
+			}
 		}
-
 		set = map[string]interface{}{
 			//"s_name":       s_name,                        //项目名称
 			//"s_entname":    s_entname,                     //公司名称
@@ -545,6 +555,7 @@ func (f *Front) ProjectGroupTaskSave() {
 				"s_entname":     qu.ObjToString((*project)["s_entname"]),    //公司名称
 				"s_departname":  qu.ObjToString((*project)["s_departname"]), //部门名称
 				"s_rulename":    qu.ObjToString((*project)["s_rulename"]),   //规则名称
+				"s_datatype":    qu.ObjToString((*project)["s_datatype"]),   //数据类型
 			}
 			realNum = realNum - givenum
 			taskArr = append(taskArr, groupTask)
@@ -1173,6 +1184,9 @@ func GetDataById(idInfoArr []util.Data, importType, s_sourceinfo string, success
 				//抽取表字段合并到bidding
 				if extData != nil && len(*extData) > 0 {
 					for k, v := range *extData {
+						if k == "publishtime" {
+							continue
+						}
 						(*bidData)[k] = v
 					}
 				}

+ 120 - 26
src/front/remark.go

@@ -17,6 +17,10 @@ import (
 	"util"
 )
 
+var (
+	purchasingField = map[string]string{"itemname": "名称", "brandname": "品牌", "modal": "型号", "unitprice": "单价", "number": "数量"}
+)
+
 func (f *Front) RemarkList() {
 	qu.Catch()
 	pid := qu.ObjToString(f.GetString("pid"))
@@ -659,6 +663,10 @@ func (f *Front) CheckList() {
 		}
 		if status != "-1" { //任务状态
 			query["s_status"] = status
+		} else {
+			query["s_status"] = map[string]interface{}{
+				"$in": []string{"未开始", "进行中", "已完成"},
+			}
 		}
 		if search != "" {
 			query["$or"] = []interface{}{
@@ -785,6 +793,7 @@ func (f *Front) CheckJyData() {
 		}
 		status := f.GetString("s_status")
 		s_excp := f.GetString("s_excp")
+		s_isEff := f.GetString("isEff")
 		field := f.GetString("field")         //字段
 		dataType1 := f.GetString("datatype1") //信息类型
 		min := f.GetString("minval")          //min max不用int类型接收,以免有默认值0
@@ -796,6 +805,11 @@ func (f *Front) CheckJyData() {
 		} else if status == "-1" {
 			query["b_check"] = false
 		}
+		if s_isEff == "1" {
+			query["b_isEff"] = true
+		} else if s_isEff == "-1" {
+			query["b_isEff"] = false
+		}
 		if s_excp == "1" {
 			query["s_excp"] = nil
 		} else if s_excp == "-1" {
@@ -872,7 +886,7 @@ func (f *Front) CheckJyData() {
 		}
 		qu.Debug(query)
 		count := util.Mgo.Count(sourceinfo, query)
-		fields := map[string]interface{}{"v_baseinfo.title": 1, "b_check": 1, "i_ckdata": 1, "s_login": 1, "b_istag": 1, "s_excp": 1, "s_excp_info": 1}
+		fields := map[string]interface{}{"v_baseinfo.title": 1, "b_check": 1, "i_ckdata": 1, "s_login": 1, "b_istag": 1, "s_excp": 1, "s_excp_info": 1, "b_isEff": 1}
 		info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, fields, false, start, limit)
 		f.ServeJson(map[string]interface{}{
 			"draw":            draw,
@@ -929,6 +943,7 @@ func (f *Front) CheckJyData() {
 			f.T["taskTagNum"] = tagCount
 			f.T["taskCheckNum"] = checkCount
 		}
+		project, _ := util.Mgo.FindById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"purchasinglist_key": 1})
 		f.T["pid"] = pid
 		f.T["tid"] = tid
 		f.T["gid"] = gid
@@ -937,6 +952,7 @@ func (f *Front) CheckJyData() {
 		f.T["datatype"] = datatype
 		f.T["topsubtype"] = util.TopSubStypeArr
 		f.T["allfield"] = util.AllFieldArr
+		f.T["purchasinglist_key"] = (*project)["purchasinglist_key"]
 		_ = f.Render("project/check_data_list.html", &f.T)
 	}
 }
@@ -1086,17 +1102,19 @@ func (f *Front) CheckSave() {
 	for k, _ := range baseUnset {
 		allTagFields[k] = nil
 	}
-	qu.Debug("allTagFields===", allTagFields)
-	qu.Debug("tagSet===", tagSet)
+	//qu.Debug("allTagFields===", allTagFields)
+	//qu.Debug("tagSet===", tagSet)
 
 	// 质检时,标注标记变成质检标记
 	checkFields, _ := (*project)["v_fields"].(map[string]interface{})
+	//datatype := qu.ObjToString((*project)["s_datatype"])
+	qu.Debug(checkFields)
 	checkSet := make(map[string]interface{})
 	for k := range checkFields {
 		checkSet[k] = tagSet[k]
 	}
 
-	if len(checkSet) > 0 || baseInfo["purchasinglist_alltag"] != nil { //purchasinglist_alltag特殊处理
+	if len(tagSet) > 0 || baseInfo["purchasinglist_alltag"] != nil { //purchasinglist_alltag特殊处理
 		//1、更新数据源信息
 		setResult := map[string]interface{}{ //更新字段集
 			"i_updatetime": time.Now().Unix(),
@@ -1134,7 +1152,6 @@ func (f *Front) CheckSave() {
 		if len(baseUnsetResult) > 0 {
 			set["$unset"] = baseUnsetResult
 		}
-		qu.Debug("set---", set)
 		success = util.Mgo.UpdateById(sourceInfo, infoId, set)
 		//2、更新marked表
 		tmp, _ := util.Mgo.FindById(sourceInfo, infoId, map[string]interface{}{"v_baseinfo": 1, "v_taginfo": 1, "i_ckdata": 1})
@@ -1207,6 +1224,21 @@ func (f *Front) CheckResult() {
 		f.ServeJson(map[string]interface{}{"rep": false, "msg": "无质检审核数据!"})
 		return
 	}
+	// 排序
+	fields := (*projcet)["v_fields"].(map[string]interface{})
+	purchasingTag := false // 标的物统计标识
+	var strs []string
+	if fields["purchasinglist"] != nil {
+		purchasingTag = true
+		delete(fields, "purchasinglist")
+	}
+	for k := range fields {
+		strs = append(strs, k)
+	}
+	pNum, pEffNum := 0, 0               // 标的物数量, 标的物有效数量
+	fieldNumMap := make(map[string]int) //字段总标注量,
+	tagNumMap := make(map[string]int)   //字段标注数据量(标的物有效)
+	rightNumMap := make(map[string]int) //正确数据(标的物有效)
 	for tmp := make(map[string]interface{}); result.Next(&tmp); markNum++ {
 		user := qu.ObjToString(tmp["s_login"])
 		var up map[string]int
@@ -1243,10 +1275,42 @@ func (f *Front) CheckResult() {
 				}
 			}
 		}
-	}
+		if tmp["b_check"].(bool) && purchasingTag {
+			info := tmp["v_baseinfo"].(map[string]interface{})
+			checkInfo := tmp["v_checkinfo"].(map[string]interface{})
+			if pList, o := info["purchasinglist"].([]interface{}); o {
+				pNum += len(pList)
+				if tmp["b_isEff"].(bool) {
+					pEffNum += 1
+				}
+				for _, p := range pList {
+					p1 := p.(map[string]interface{})
+					for f := range purchasingField {
+						if qu.ObjToString(p1[f]) != "" {
+							fieldNumMap[f] += 1
+							if b, o := p1["b_isEff"].(bool); b && o {
+								tagNumMap[f] += 1
+							}
+						}
+					}
+				}
+			}
+			if cList, o := checkInfo["purchasinglist"].([]interface{}); o {
+				for _, c := range cList {
+					c1 := c.(map[string]interface{})
+					for f := range purchasingField {
 
+						if qu.IntAll(c1[f]) == 1 {
+							rightNumMap[f] += 1
+						}
+					}
+				}
+			}
+		}
+	}
 	qu.Debug(cmaps)
 	qu.Debug(umaps)
+	pResult := method(fieldNumMap, tagNumMap, rightNumMap)
 	// 前台页面数据
 	dataSource := make(map[string]interface{})
 	var userSelect []string
@@ -1259,12 +1323,7 @@ func (f *Front) CheckResult() {
 	tmp["num3"] = checkNumR
 	tmp["num4"] = CountPr(checkNumR, checkNum)
 	dataSelect = append(dataSelect, tmp)
-	// 排序
-	fields := (*projcet)["v_fields"].(map[string]interface{})
-	var strs []string
-	for k := range fields {
-		strs = append(strs, k)
-	}
+
 	sort.Strings(strs)
 	for _, v := range strs {
 		tmp1 := make(map[string]interface{})
@@ -1287,7 +1346,7 @@ func (f *Front) CheckResult() {
 			tmp2["num3"] = v2["re_rg_count"]
 			tmp2["num4"] = CountPr(v2["re_rg_count"], v2["re_count"])
 			dataSelect1 = append(dataSelect1, tmp2)
-			for k, v := range (*projcet)["v_fields"].(map[string]interface{}) {
+			for k, v := range fields {
 				tmp1 := make(map[string]interface{})
 				tmp1["name"] = v
 				tmp1["num1"] = v2["ck_count"]
@@ -1299,6 +1358,8 @@ func (f *Front) CheckResult() {
 			dataSource[k1] = dataSelect1
 		}
 	}
+	qu.Debug("字段统计---", dataSource)
+	qu.Debug("字段统计---", pResult)
 	f.T["pid"] = pid
 	f.T["tid"] = tid
 	f.T["sourceinfo"] = sourceinfo
@@ -1306,11 +1367,30 @@ func (f *Front) CheckResult() {
 	f.T["taskTagNum"] = markNum
 	f.T["taskCheckNum"] = checkNum
 	f.T["taskCheckRight"] = checkNumR
+	f.T["pNum"] = pNum       // 标的物数量
+	f.T["pEffNum"] = pEffNum //标的物有效数据量
 	f.T["tableData"] = dataSource
+	f.T["pResult"] = pResult
 	f.T["userSelect"] = userSelect
 	_ = f.Render("project/check_result.html", &f.T)
 }
 
+// @Description 标的物统计结果
+// @Author J 2022/4/25 2:20 PM
+func method(m1, m2, m3 map[string]int) []map[string]interface{} {
+	var result []map[string]interface{}
+	for f, v := range purchasingField {
+		m := make(map[string]interface{})
+		m["name"] = v
+		m["num"] = m1[f]
+		m["num1"] = m2[f]
+		m["num2"] = m3[f]
+		m["num3"] = CountPr(m2[f], m3[f])
+		result = append(result, m)
+	}
+	return result
+}
+
 // CountPr 计算百分比
 func CountPr(c1, c2 int) string {
 	decimal.DivisionPrecision = 2
@@ -1384,7 +1464,7 @@ func (f *Front) CheckExcpData() {
 	f.ServeJson(map[string]interface{}{"success": true})
 }
 
-var regReplAllSymbol = regexp.MustCompile("[(\\(<《【\\[{{〔)\\)>》】\\]}}〕,,;;::'\"“”。.\\??/+=\\-_—*&……\\^%$¥@#!!`~·]")
+var regReplAllSymbol = regexp.MustCompile("[<《【\\[{{〔>》】\\]}}〕,,;;::'\"“”。.??/+=\\-_—*&…^%$¥@#!!`~·]")
 
 func DataException(tmp map[string]interface{}) (string, string) {
 	var tag []string
@@ -1969,30 +2049,32 @@ func MarkTimePlace(content []interface{}, tagSet, baseSet, baseUnset map[string]
 	qu.Debug("baseUnset===", baseUnset)
 }
 
-// MarkPurchasinglist 标注标的信息
 func MarkPurchasinglist(content []interface{}, tagSet, baseSet, baseUnset map[string]interface{}, istag bool, status int) {
 	if status == -1 {
 		return
 	}
 	baseSet["purchasinglist_alltag"] = istag //标的信息是否标注完全
 	purchasinglist := []interface{}{}
+	purchasinglistStatus := []interface{}{}
 	delpclson := 0
 	for _, con := range content {
 		info, _ := con.(map[string]interface{})
-		isNew, _ := info["isnew"].(bool) //是否是新增子包
+		//isNew, _ := info["isnew"].(bool) //是否是新增子包
 		pclSonStatus := qu.IntAll(info["status"])
 		if pclSonStatus == 4 {
 			delpclson++
 		}
 		if uInputs, ok := info["uInput"].([]interface{}); ok {
 			result := map[string]interface{}{
-				"isnew": isNew,
+				//"isnew": isNew,
 			}
+			statusMap := make(map[string]interface{})
 			for _, tmp := range uInputs {
 				if tmpMap, ok := tmp.(map[string]interface{}); ok {
 					key := qu.ObjToString(tmpMap["key"]) //字段
 					input := tmpMap["input"]             //值
-					//status := qu.IntAll(tmpMap["status"])
+					status := qu.IntAll(tmpMap["status"])
+					statusMap[key] = status
 					isNull := false
 					if input == "" { //判断前台页面是否填值,无值不进行字段存储
 						isNull = true
@@ -2009,6 +2091,7 @@ func MarkPurchasinglist(content []interface{}, tagSet, baseSet, baseUnset map[st
 			}
 			if len(result) > 0 && pclSonStatus != 4 {
 				purchasinglist = append(purchasinglist, result)
+				purchasinglistStatus = append(purchasinglistStatus, statusMap)
 			}
 		}
 	}
@@ -2019,7 +2102,8 @@ func MarkPurchasinglist(content []interface{}, tagSet, baseSet, baseUnset map[st
 		} else if len(content) > 0 && delpclson == len(content) { //只有删除
 			baseUnset["purchasinglist"] = ""
 		}
-		tagSet["purchasinglist"] = status
+		//tagSet["purchasinglist"] = status
+		tagSet["purchasinglist"] = purchasinglistStatus
 	} else {
 		qu.Debug("Purchasinglist Tag Error")
 	}
@@ -2261,6 +2345,7 @@ func (f *Front) CheckDataPurchase() {
 		stype := f.GetString("stype")
 		sourceinfo := f.GetString("s_sourceinfo")
 		tid := f.GetString("taskid")
+		pid := f.GetString("pid")
 		keyword := f.GetString("keyword")
 		keyword = strings.ReplaceAll(keyword, ",", ",")
 		keyArr := strings.Split(keyword, ",")
@@ -2290,30 +2375,40 @@ func (f *Front) CheckDataPurchase() {
 				query["i_ckdata"] = 2
 			}
 		}
+		util.Mgo.UpdateById(util.PROJECTCOLLNAME, pid, map[string]interface{}{"$set": map[string]interface{}{"purchasinglist_key": keyword}})
 		query["v_baseinfo.purchasinglist"] = map[string]interface{}{"$exists": true}
 		count := util.Mgo.Count(sourceinfo, query)
 		qu.Debug(query, count)
-		info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, `{"v_baseinfo": 1, "b_isEff": 1}`, false, -1, -1)
+		info, _ := util.Mgo.Find(sourceinfo, query, `{"_id": 1}`, `{"v_baseinfo": 1, "b_isEff": 1, "v_checkinfo": 1, "v_taginfo": 1}`, false, -1, -1)
 		var updateArr [][]map[string]interface{}
 		for _, m := range *info {
 			baseinfo := m["v_baseinfo"].(map[string]interface{})
+			//taginfo := m["v_taginfo"].(map[string]interface{})
+			//checkinfo := m["v_checkinfo"].(map[string]interface{})
+			//var pursTag, pursCheck []interface{}
 			purs := baseinfo["purchasinglist"].([]interface{})
+			//if taginfo["purchasinglist"] != nil {
+			//	pursTag = taginfo["purchasinglist"].([]interface{})
+			//}
+			//if checkinfo["purchasinglist"] != nil {
+			//	pursCheck = checkinfo["purchasinglist"].([]interface{})
+			//}
 			if len(purs) > 0 {
-				arr1 := []map[string]interface{}{} //质检通过
-				arr2 := []map[string]interface{}{} //质检未通过
+				//arr1 := []map[string]interface{}{} //检通过
+				//arr2 := []map[string]interface{}{} //检未通过
 				for _, m2 := range qu.ObjArrToMapArr(purs) {
 					if validPurchase(keyArr, qu.ObjToString(m2["itemname"])) {
 						m2["b_isEff"] = true
 						if m["b_isEff"] != nil && !m["b_isEff"].(bool) {
 							m["b_isEff"] = true
 						}
-						arr1 = append(arr1, m2)
+						//arr1 = append(arr1, m2)
 					} else {
 						m2["b_isEff"] = false
-						arr2 = append(arr2, m2)
+						//arr2 = append(arr2, m2)
 					}
 				}
-				baseinfo["purchasinglist"] = append(arr1, arr2...)
+				//baseinfo["purchasinglist"] = append(arr1, arr2...)
 				var update []map[string]interface{}
 				update = append(update, map[string]interface{}{"_id": m["_id"]})
 				update = append(update, map[string]interface{}{"$set": m})
@@ -2326,7 +2421,6 @@ func (f *Front) CheckDataPurchase() {
 			}
 		}
 		if len(updateArr) > 0 {
-			qu.Debug(updateArr)
 			util.Mgo.UpSertBulk(sourceinfo, updateArr...)
 		}
 		f.ServeJson(map[string]interface{}{"success": true, "msg": ""})

+ 4 - 0
src/front/user.go

@@ -755,6 +755,10 @@ func (f *Front) UserTaskList() {
 		}
 		if status != "-1" { //任务状态
 			query["s_status"] = status
+		} else {
+			query["s_status"] = map[string]interface{}{
+				"$in": []string{"未开始", "进行中", "已完成"},
+			}
 		}
 		if search != "" {
 			query["$or"] = []interface{}{

+ 1 - 0
src/main.go

@@ -34,5 +34,6 @@ func init() {
 }
 
 func main() {
+
 	xweb.Run(":" + qu.ObjToString(Sysconfig["port"]))
 }

+ 6 - 1
src/util/config.go

@@ -40,6 +40,7 @@ var (
 	AllFieldArr          []map[string]string
 	TopSubStypeArr       []string
 	TopSubStypeArr2      []string
+	FieldsMap            map[string]interface{}
 	DataTypeArr          []string
 	DataTypeMap          map[string]interface{} //项目中数据类型
 )
@@ -235,7 +236,11 @@ func InitConfig() {
 	for k := range DataTypeMap {
 		DataTypeArr = append(DataTypeArr, k)
 	}
-
+	info, _ := Mgo.Find("v_field", `{"s_type": "tag"}`, nil, nil, false, -1, -1)
+	FieldsMap = make(map[string]interface{})
+	for _, m := range *info {
+		FieldsMap[qu.ObjToString(m["s_code"])] = m["s_name"]
+	}
 	initQuaConfig()
 }
 

BIN
src/web/model/taskstatsmodel.xlsx


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

@@ -44,10 +44,12 @@
                             </div>
                             <input type="button" class="btn btn-primary" onclick="checkResult()" value="质检结果">
                             <input type="button" class="btn btn-primary" onclick="checkExcpResult()" value="异常校验结果">
+
+                            <input type="button" id="wbCheckBtn" style="display: none" class="btn btn-primary" onclick="checkResultWb()" value="查看外包质检结果">
                         </div>
                         <div class="col-xs-10" style="margin-left: 10px;margin-top: 10px">
                             <label class="form-inline">标的物关键词校验:
-                                <input type="text" id="purchase" class="form-control" style="width: 420px;padding: 5px" value="">
+                                <input type="text" id="purchase" class="form-control" style="width: 420px;padding: 5px" value="{{ .T.purchasinglist_key }}">
                             </label>
                             <input type="button" class="btn btn-primary" onclick="validPurchase()" style="margin-left: 10px" value="标的物有效性校验">
                         </div>
@@ -82,15 +84,22 @@
                             <select class="form-control selectpicker" id="dataSelect">
                                 <option value="0">全部</option>
                                 <option value="1">正常</option>
-                                <option value="-1" selected>异常</option>
+                                <option value="-1">异常</option>
                             </select>
                         </label>
+                        <label for="statusSelect" class="form-inline">标的物状态:
+                            <select class="form-control selectpicker" id="purchasingSelect">
+                                <option value="0">全部</option>
+                                <option value="1">检验有效</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>
                             <th>标题</th>
                             <th>用户</th>
                         </tr>
@@ -114,6 +123,7 @@
     }else if (router === "group") {
         $('ol[name="tab3"]').show()
         menuActive("/front/group/task/list");
+        $('#wbCheckBtn').show()
     }else if (router === "task") {
         $('ol[name="tab4"]').show()
         menuActive("/front/user/check/list");
@@ -173,6 +183,15 @@
                         }
                         return tmp
                     }},
+                {"data": "b_isEff", width: "5%", render: function (val) {
+                        let tmp;
+                        if (val) {
+                            tmp = '<span style="display: inline-block;font-size:14px;">检查有效</span>'
+                        } else {
+                            tmp = '<span style="display: inline-block;font-size:14px;">检查无效</span>'
+                        }
+                        return tmp
+                    }},
                 {"data": "v_baseinfo.title", render: function (val, index, row) {
                         let tmp
                         if (row["b_check"]) {
@@ -192,6 +211,7 @@
                 e.s_excp = $("#dataSelect option:selected").val()
                 e.datatype1 = $("#typeSelect option:selected").val()
                 e.field = $("#fieldSelect option:selected").val()
+                e.isEff = $("#purchasingSelect option:selected").val()
                 if (e.field !== "-1") {
                     e.hasno = $("#field-exist").is(':checked')
                     e.notag = $("#field-tag").is(':checked')
@@ -227,6 +247,9 @@
         $('#typeSelect').on('changed.bs.select', function () {
             ttable.api().ajax.reload();
         })
+        $('#purchasingSelect').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()
@@ -256,6 +279,20 @@
             showTip("没有审核数据")
         }
     }
+    function checkResultWb() {
+        $.ajax({
+            url: "/front/group/check/wb/result",
+            type: 'POST',
+            data: {"tid": tid, "pid": pid, "s_sourceinfo": sourceinfo},
+            success: function (r) {
+                if (r.success) {
+                    window.location.href = "/front/group/check/wb/result?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}"
+                } else {
+                    showTip(r.msg);
+                }
+            }
+        })
+    }
     function checkExcpResult() {
         window.location.href = "/front/check/excp/result?pid={{.T.pid}}&tid={{.T.tid}}&s_sourceinfo={{.T.sourceinfo}}&stype={{.T.stype}}&datatype={{.T.datatype}}"
     }
@@ -270,11 +307,11 @@
         $.ajax({
             url: "/front/check/data/purchase",
             type: 'POST',
-            data: {"s_sourceinfo": sourceinfo, "taskid": tid, "datatype": datatype, "keyword": ps},
+            data: {"s_sourceinfo": sourceinfo, "taskid": tid, "pid": pid, "datatype": datatype, "keyword": ps},
             success: function (r) {
                 hideLoading()
                 if (r.success) {
-                    // location.reload()
+                    showTip("校验成功!")
                 } else {
                     showTip(r.msg);
                 }

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

@@ -1380,6 +1380,7 @@
                 },
                 //保存事件
                 upChange: function (stype) {
+                    console.log(this.editData)
                     var d = JSON.stringify(this.editData);
                     var _this = this
                     $.ajax({

+ 91 - 28
src/web/templates/project/check_result.html

@@ -29,38 +29,79 @@
     </section>
     <!-- Main content -->
     <section class="content">
-        <div class="row">
-            <div class="col-xs-12">
-                <div class="box">
-                    <div class="box-body">
+        <div class="tab-content">
+            <div class="nav-tabs-custom">
+                <ul class="nav nav-tabs">
+                    <li class="active" data-mode="guide"><a href="#tab_1" data-toggle="tab" aria-expanded="true">字段统计</a></li>
+                    <li data-mode="guide" class=""><a href="#tab_2" data-toggle="tab" aria-expanded="false">标的物统计</a></li>
+                </ul>
+                <div class="tab-content">
+                    <div class="tab-pane active" id="tab_1">
+                        <div class="row">
+                            <div class="col-xs-12">
+                                <div class="box">
+                                    <div class="box-body">
+                                        <div class="box-body">
+                                            <h4><i class="glyphicon glyphicon-exclamation-sign" style="margin-right: 6px"></i>数据情况</h4>
+                                            <div class="form-group" style="margin-left: 10px;margin-top: 10px">
+                                                <div class="col-xs-5" style="width: auto">
+                                                    <label class="form-inline">已检数据/数据总量:
+                                                        <input type="text" class="form-control" readonly value="{{.T.taskCheckNum}} / {{ .T.taskNum }}"></label>
+                                                    <!--                                    <label class="form-inline">已检数据/已标总量:-->
+                                                    <!--                                        <input type="text" class="form-control" readonly value="{{.T.taskCheckNum}} / {{ .T.taskTagNum }}"></label>-->
+                                                </div>
+                                            </div>
+                                        </div>
 
-                        <div class="box-body">
-                            <h4><i class="glyphicon glyphicon-exclamation-sign" style="margin-right: 6px"></i>数据情况</h4>
-                            <div class="form-group" style="margin-left: 10px;margin-top: 10px">
-                                <div class="col-xs-5" style="width: auto">
-                                    <label class="form-inline">已检数据/数据总量:
-                                        <input type="text" class="form-control" readonly value="{{.T.taskCheckNum}} / {{ .T.taskNum }}"></label>
-<!--                                    <label class="form-inline">已检数据/已标总量:-->
-<!--                                        <input type="text" class="form-control" readonly value="{{.T.taskCheckNum}} / {{ .T.taskTagNum }}"></label>-->
+                                        <div id="status-div" class="col-xs-5 form-inline" style="width: auto;float:right;">
+                                            <label for="statusSelect">用户:
+                                                <select class="form-control selectpicker" id="statusSelect"></select></label>
+                                        </div>
+                                        <table id="dataTable" class="table table-bordered table-hover">
+                                            <thead>
+                                            <tr>
+                                                <th>名称</th>
+                                                <th>标注数量</th>
+                                                <th>抽查数量</th>
+                                                <th>抽查正确数量</th>
+                                                <th>正确占比</th>
+                                            </tr>
+                                            </thead>
+                                        </table>
+                                    </div>
                                 </div>
                             </div>
                         </div>
-
-                        <div id="status-div" class="col-xs-5 form-inline" style="width: auto;float:right;">
-                            <label for="statusSelect">用户:
-                                <select class="form-control selectpicker" id="statusSelect"></select></label>
+                    </div>
+                    <div class="tab-pane" id="tab_2">
+                        <div class="row">
+                            <div class="col-xs-12">
+                                <div class="box">
+                                    <div class="box-body">
+                                        <div class="box-body">
+                                            <h4><i class="glyphicon glyphicon-exclamation-sign" style="margin-right: 6px"></i>数据情况</h4>
+                                            <div class="form-group" style="margin-left: 10px;margin-top: 10px">
+                                                <div class="col-xs-5" style="width: auto">
+                                                    <label class="form-inline">标的物有效数据量/标的物总数据量:
+                                                        <input type="text" class="form-control" readonly value="{{.T.pEffNum}} / {{ .T.pNum }}"></label>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <table id="purchasing" class="table table-bordered table-hover">
+                                            <thead>
+                                            <tr>
+                                                <th>字段</th>
+                                                <th>字段标注总数据量</th>
+                                                <th>字段标注有效数据量</th>
+                                                <th>字段标注有效正确数据量</th>
+                                                <th>正确占比</th>
+                                            </tr>
+                                            </thead>
+                                        </table>
+                                    </div>
+                                </div>
+                            </div>
                         </div>
-                        <table id="dataTable" class="table table-bordered table-hover">
-                            <thead>
-                            <tr>
-                                <th>名称</th>
-                                <th>标注数量</th>
-                                <th>抽查数量</th>
-                                <th>抽查正确数量</th>
-                                <th>正确占比</th>
-                            </tr>
-                            </thead>
-                        </table>
                     </div>
                 </div>
             </div>
@@ -87,6 +128,7 @@
 
     let dataResult = {{ .T.tableData }}
     let userSelect = {{ .T.userSelect }}
+    let pDataResult = {{ .T.pResult }}
 
     $(function () {
         ttable = $('#dataTable').dataTable({
@@ -111,11 +153,32 @@
                 $("#dataTable_filter").append($('#status-div'))
             },
         });
+        ttable1 = $('#purchasing').dataTable({
+            "paging": false,
+            "lengthChange": false,
+            "searching": false,
+            "ordering": false,
+            "info": true,
+            "autoWidth": false,
+            "serverSide": false,
+            "language": {
+                "url": "/dist/js/dataTables.chinese.lang"
+            },
+            "columns": [
+                {"data": "name"},
+                {"data": "num"},
+                {"data": "num1"},
+                {"data": "num2"},
+                {"data": "num3"}
+            ]
+        });
 
         ttable.fnClearTable();
         ttable.fnAddData(dataResult["全部"]);
+        ttable1.fnClearTable();
+        ttable1.fnAddData(pDataResult);
         console.log(dataResult)
-        console.log(dataResult)
+        console.log(pDataResult)
         for(i in userSelect){
             $("#statusSelect").append("<option value='"+userSelect[i]+"'>"+userSelect[i]+"</option>")
         }

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

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

+ 23 - 13
src/web/templates/project/project_list.html

@@ -213,6 +213,12 @@
                                         <select class="form-control selectpicker" id="dataTypeSelect" title="请选择"></select>
                                     </div>
                                 </div>
+                                <div class="form-group">
+                                    <label class="col-sm-3 control-label"></label>
+                                    <div class="col-sm-5">
+                                        <span type="text" id="dataTypeStr" style="font-size: 10px;text-align: center;white-space: normal;word-wrap: break-word;"></span>
+                                    </div>
+                                </div>
                                 <div class="form-group">
                                     <label class="col-sm-3 control-label">选择标注字段</label>
                                     <div class="col-sm-5">
@@ -477,10 +483,10 @@
             $('#dataTypeSelect')[0].appendChild(opt)
         }
         $("#dataTypeSelect").selectpicker("refresh");
-        for (let i in fields) {
+        for (let k in fields) {
             let opt = document.createElement('option');
-            opt.innerText = fields[i]["s_name"];
-            opt.value = fields[i]["s_code"];
+            opt.innerText = fields[k];
+            opt.value = k;
             $('#markFieldSelect')[0].appendChild(opt)
         }
         $("#markFieldSelect").selectpicker("refresh");
@@ -500,6 +506,9 @@
         $('#statusSelect').on('changed.bs.select', function () {
             ttable.api().ajax.reload();
         })
+        $('#dataTypeSelect').on('changed.bs.select', function () {
+            $("#dataTypeStr").html(dataTypeMap[$(this).val()].toString())
+        })
     });
 
     function createPro() {
@@ -624,6 +633,7 @@
                 }
             })
             $("#dataTypeSelect").selectpicker("refresh");
+            $("#dataTypeStr").html(dataTypeMap[projectmap.s_datatype].toString())
         }else {
             $("#dataTypeSelect").selectpicker("deselectAll");
         }
@@ -647,20 +657,20 @@
         let m = {}
         let m1 = {}
         let arr = dataTypeMap[type]
-        for (const i in fields) {
-            if (fieldArr.indexOf(fields[i]["s_code"]) > -1) {
-                m[fields[i]["s_code"]] = fields[i]["s_name"]
-                m1[fields[i]["s_code"]] = fields[i]["s_name"]
+        for (const k in fields) {
+            if (fieldArr.indexOf(k) > -1) {
+                m[k] = fields[k]
+                // m1[fields[i]["s_code"]] = fields[i]["s_name"]
             }else {
-                if (arr.indexOf(fields[i]["s_code"]) > -1) {
-                    m1[fields[i]["s_code"]] = fields[i]["s_name"]
-                }
+                // if (arr.indexOf(fields[i]["s_code"]) > -1) {
+                //     m1[fields[i]["s_code"]] = fields[i]["s_name"]
+                // }
             }
         }
         console.log(m)
-        console.log(m1)
+        // console.log(m1)
         tmp["v_fields_diy"] = JSON.stringify(m)
-        tmp["v_fields"] = JSON.stringify(m1)
+        // tmp["v_fields"] = JSON.stringify(m1)
         if (s1 === JSON.stringify(tmp)) {
             showTip("未做修改");
         } else {
@@ -669,7 +679,7 @@
                 type: 'POST',
                 data: {"s_type": stype, "s_departname": tmp["s_departname"], "s_personname": tmp["s_personname"],
                     "s_rulename": tmp["s_rulename"], "v_fields_diy": tmp["v_fields_diy"], "s_name": tmp["s_name"],
-                    "v_fields": tmp["v_fields"], "s_datatype": type},
+                    "s_datatype": type},
                 success: function (r) {
                     if (r.success) {
                         showTip("保存成功", 500)

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

@@ -162,4 +162,5 @@
         sessionStorage.setItem("check", "group")
         window.location.href = "/front/jy/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=group"
     }
+
 </script>

+ 27 - 5
src/web/templates/project/task_list.html

@@ -3,6 +3,7 @@
 {{include "com/header.html"}}
 <!-- Left side column. 权限菜单 -->
 {{include "com/menu.html"}}
+
 <div class="content-wrapper" xmlns="http://www.w3.org/1999/html">
     <section class="content-header">
         <h1><small></small></h1>
@@ -39,6 +40,7 @@
                                   </span>
                             </span>
                         <input type="button" class="btn btn-sm btn-primary" onclick="exportTask()" value="导出">
+                        <input type="button" class="btn btn-sm btn-primary" onclick="statsTask()" value="统计">
                         <!--                            <a type="button" class="btn btn-sm btn-primary" href="/front/group/task/export">导出</a>-->
                     </div>
 
@@ -47,10 +49,9 @@
                         <tr>
                             <th></th>
                             <th>公司名称</th>
-                            <th>部门名称</th>
-                            <th>规则名称</th>
                             <th>项目名称</th>
                             <th>用户组名称</th>
+                            <th>数据类型</th>
                             <th>负责人</th>
                             <th>清洗数据量</th>
                             <th>任务状态</th>
@@ -104,10 +105,9 @@
             "columns": [
                 {"data": null, width: "1%"},
                 {"data": "s_entname", width: "4%"},
-                {"data": "s_departname", width: "4%"},
-                {"data": "s_rulename", width: "4%"},
                 {"data": "s_projectname", width: "4%"},
                 {"data": "s_groupname", width: "4%"},
+                {"data": "s_datatype", width: "4%", },
                 {"data": "s_personname", width: "4%"},
                 {"data": "i_givenum", width: "4%"},
                 {"data": "s_status", width: "4%"},
@@ -175,7 +175,6 @@
                 }
             }
         });
-
         $('.date-picker').datepicker({
             language: 'zh-CN',
             autoclose: true,
@@ -290,4 +289,27 @@
         sessionStorage.setItem("check", "jygroup")
         window.location.href = "/front/jy/check/data?pid="+pid+"&tid="+tid+"&s_sourceinfo="+sourceinfo+"&stype=group"
     }
+
+    function statsTask() {
+        console.log(ttable.fnGetData())
+        let search = $("[type=search]").val();
+        let status = $("#statusSelect option:selected").val()
+        let st = $('#starttime').datepicker('getDate')
+        let et = $('#endtime').datepicker('getDate')
+        let sttime = 0
+        let edtime = 0
+        if (st != null) {
+            let stc = st.toLocaleDateString()
+            sttime = Date.parse(new Date(stc).toString())/1000
+        }else {
+            sttime = 0
+        }
+        if (et != null) {
+            let etc = et.toLocaleDateString()
+            edtime = Date.parse(new Date(etc).toString())/1000
+        }else {
+            edtime = 0
+        }
+        window.location.href = "/front/group/task/stats?"+"i_starttime="+sttime+"&i_completetime="+edtime+"&s_search="+search+"&s_status="+status
+    }
 </script>

+ 124 - 0
src/web/templates/project/task_list_stats.html

@@ -0,0 +1,124 @@
+{{include "com/inc.html"}}
+<!-- Main Header -->
+{{include "com/header.html"}}
+<!-- Left side column. 权限菜单 -->
+{{include "com/menu.html"}}
+
+<div class="content-wrapper" xmlns="http://www.w3.org/1999/html">
+    <section class="content-header">
+        <h1><small></small></h1>
+        <ol class="breadcrumb">
+            <li><a href="#"><i class="fa fa-dashboard"></i> 剑鱼任务列表</a></li>
+            <li><a href="#"><i class="fa fa-dashboard"></i> 任务统计</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="row">
+            <div class="box">
+                <div class="box-body">
+                    <div id="status-div" class="col-xs-1" style="width: auto;float: right">
+                        <input type="button" class="btn btn-sm btn-primary" onclick="exportTask()" value="数据导出">
+                    </div>
+                    <table id="dataTable" class="table table-bordered table-hover">
+                        <thead>
+                        <tr>
+                            <th></th>
+                            <th>项目名称</th>
+                            <th>用户组名称</th>
+                            <th>数据类型</th>
+                            <th>数据量</th>
+                        </tr>
+                        </thead>
+                    </table>
+                </div>
+                <!-- /.box-body -->
+            </div>
+            <!-- /.box -->
+        </div>
+    </section>
+</div>
+
+{{include "com/footer.html"}}
+<script>
+    menuActive("/front/group/admin/task/list");
+
+    let datasource = {{ .T.datasource }}
+
+    $(function () {
+        ttable = $('#dataTable').dataTable({
+            "paging": false,
+            "lengthChange": false,
+            "searching": false,
+            "ordering": false,
+            "info": true,
+            "autoWidth": true,
+            "serverSide": false,
+            "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},
+                {"data": "s_projectname"},
+                {"data": "s_groupname"},
+                {"data": "s_datatype"},
+                {"data": "num"},
+            ]
+        });
+
+        console.log(datasource)
+        ttable.fnClearTable();
+        ttable.fnAddData(datasource);
+    });
+
+    function exportTask() {
+        // window.location.href = "/front/group/task/stats/export?param="+JSON.stringify(datasource)
+        $.ajax({
+            url: "/front/group/task/stats/export",
+            type: 'POST',
+            xhrFields: { responseType: 'arraybuffer'},
+            data: {"param": JSON.stringify(datasource)},
+            success: function (r, status, xhr) {
+                downloadFile(r, "下载")
+            }
+        })
+    }
+    function downloadFile(res, fileName) { // res为后端传来的文件流,// fileName为文件名称,自己根据实际情况赋值
+        if (!res) {
+            return
+        }
+        if (window.navigator.msSaveBlob) { // IE以及IE内核的浏览器
+            try {
+                window.navigator.msSaveBlob(res, fileName) // res为接口返回数据,这里请求的时候已经处理了,如果没处理需要在此之前自行处理var data = new Blob([res.data]) 注意这里需要是数组形式的,fileName就是下载之后的文件名
+                // window.navigator.msSaveOrOpenBlob(res, fileName);  //此方法类似上面的方法,区别可自行百度
+            } catch (e) {
+                console.log(e)
+            }
+        } else {
+            let url = window.URL.createObjectURL(new Blob([res], {
+                type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // 前后端一定要同意utf-8编码,否则会是乱码
+            }));
+            let link = document.createElement('a')
+            link.style.display = 'none'
+            link.href = url
+            link.setAttribute('download', fileName) // 文件名
+            document.body.appendChild(link)
+            link.click()
+            document.body.removeChild(link) // 下载完成移除元素
+            window.URL.revokeObjectURL(url) // 释放掉blob对象
+        }
+    }
+</script>