Jianghan 4 mēneši atpakaļ
vecāks
revīzija
093a553f88

+ 1 - 0
src/config.json

@@ -5,6 +5,7 @@
     "dbname": "datacheck",
     "alltocoll": "marked",
     "defaultpwd": "123",
+    "redis": "repeat=127.0.0.1:6379",
     "bidding":{
         "addr":"172.20.45.129:27002",
         "db": "wjh",

+ 95 - 0
src/crons/repeat_data.go

@@ -0,0 +1,95 @@
+package crons
+
+import (
+	"fmt"
+	"go.mongodb.org/mongo-driver/bson"
+	qu "qfw/util"
+	"qfw/util/redis"
+	"strings"
+	"sync"
+	"time"
+	"util"
+)
+
+var (
+	Processing = false // redis 保存数据中
+	// 采购意向 repeat_subtype_projectname_budget_buyer
+	CgKey = "repeat_%s_%s_%f_%s"
+	// 招标、邀标、竞价、竞谈、询价
+	// repeat_subtype_city_projectname_budget_buyer
+	ZbKey = "repeat_%s_%s_%s_%f_%s"
+	// 中标、成交、单一
+	// repeat_中标_city_projectname_bidamount_projectcode_winner_buyer
+	// repeat_中标候选_city_projectname_bidamount_projectcode_winner_buyer
+	ZgbKey          = "repeat_%s_%s_%s_%f_%s_%s_%s"
+	timeout         = 14 * 24 * 3600
+	ItemOk, ItemArr = false, []string{"候选人", "侯选人", "中选公告", "中选公示", "中标公告", "中标公示", "单一来源采购公示", "单一来源采购公告", "评标结果公示", "评标结果公告", "直接采购公示"}
+)
+
+func RepeatData() {
+	sess := util.MgoJy.GetMgoConn()
+	defer util.MgoJy.DestoryMongoConn(sess)
+
+	Processing = true
+	ch := make(chan bool, 5)
+	wg := &sync.WaitGroup{}
+
+	count := 0
+	q := bson.M{"createtime": bson.M{"$gte": util.CreateTime}}
+	query := sess.DB(util.MgoJy.DbName).C("usermail_tmp_js").Find(q).Select(nil).Iter()
+	for tmp := make(map[string]interface{}); query.Next(&tmp); count++ {
+		if count%1000 == 0 {
+			qu.Debug("Repeat data current:", count)
+		}
+		if c := qu.Int64All(tmp["createtime"]); c > util.CreateTime {
+			util.CreateTime = c
+		}
+		ch <- true
+		wg.Add(1)
+		go func(tmp map[string]interface{}) {
+			defer func() {
+				<-ch
+				wg.Done()
+			}()
+			pb := qu.Int64All(tmp["publishtime"])
+			if time.Now().Unix()-pb > int64(timeout) {
+				return
+			}
+			subtype := qu.ObjToString(tmp["subtype"])
+			pname := qu.ObjToString(tmp["projectname"])
+			pcode := qu.ObjToString(tmp["projectcode"])
+			city := qu.ObjToString(tmp["city"])
+			budget := qu.Float64All(tmp["budget"])
+			bidamount := qu.Float64All(tmp["bidamount"])
+			buyer := qu.ObjToString(tmp["buyer"])
+			winner := qu.ObjToString(tmp["s_winner"])
+			if subtype == "采购意向" {
+				key := fmt.Sprintf(CgKey, subtype, pname, budget, buyer)
+				redis.Put("repeat", key, "1", timeout)
+			} else if strings.Contains("招标、邀标、竞价、竞谈、询价", subtype) {
+				key := fmt.Sprintf(ZbKey, subtype, city, pname, budget, buyer)
+				redis.Put("repeat", key, "1", timeout)
+			} else if strings.Contains("中标、成交、单一", subtype) {
+				title := qu.ObjToString(tmp["title"])
+				for _, vv := range ItemArr {
+					if strings.Contains(title, vv) {
+						ItemOk = true
+						break
+					}
+				}
+				if ItemOk {
+					key := fmt.Sprintf(ZgbKey, "候选人公式", city, pname, bidamount, pcode, winner, buyer)
+					redis.Put("repeat", key, "1", timeout)
+				} else {
+					key := fmt.Sprintf(ZgbKey, "中标通知", city, pname, bidamount, pcode, winner, buyer)
+					redis.Put("repeat", key, "1", timeout)
+				}
+			}
+		}(tmp)
+		tmp = make(map[string]interface{})
+	}
+	wg.Wait()
+	Processing = false
+	qu.Debug("Repeat data over count:", count)
+	qu.Debug("Repeat data over CreateTime:", util.CreateTime)
+}

+ 4 - 0
src/front/front.go

@@ -120,6 +120,10 @@ type Front struct {
 	checkExcpResult   xweb.Mapper `xweb:"/front/check/excp/result"`     // 异常数据
 	checkExcpData     xweb.Mapper `xweb:"/front/check/excp/notag/data"` //达标数据
 	checkDataPurchase xweb.Mapper `xweb:"/front/check/data/purchase"`   // 标的物有效性检查
+
+	//江苏 联通
+	pushRepeatData xweb.Mapper `xweb:"/front/push/repeat/data"`
+	repeatData     xweb.Mapper `xweb:"/front/repeat/repeat/data"`
 }
 
 func (f *Front) Index() {

+ 167 - 6
src/front/group.go

@@ -1,6 +1,7 @@
 package front
 
 import (
+	"crons"
 	"dataValidation/util"
 	"encoding/json"
 	"fmt"
@@ -10,12 +11,15 @@ import (
 	"io"
 	qu "jygit.jydev.jianyu360.cn/data_processing/common_utils"
 	"jygit.jydev.jianyu360.cn/data_processing/common_utils/mongodb"
+	"math"
 	"os"
+	"qfw/util/redis"
 	"sort"
 	"strconv"
 	"strings"
 	"sync"
 	"time"
+	"util"
 )
 
 // GroupTaskListByGroup 用户组权限用户组任务列表
@@ -184,7 +188,7 @@ func (f *Front) GroupUserTaskList() {
 		}
 		qu.Debug("Query:", query)
 		count := util.Mgo.Count(util.TASKCOLLNAME, query)
-		list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, map[string]interface{}{"_id": -1}, nil, false, int(start), int(limit))
+		list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, map[string]interface{}{"_id": -1}, nil, false, start, limit)
 		for _, l := range *list {
 			if status := qu.ObjToString(l["s_status"]); status == "进行中" { //更新任务进度
 				giveNum := qu.IntAll(l["i_givenum"])
@@ -336,7 +340,6 @@ func syncJyData(source, tid, pid string) int {
 				info["isOptimization"] = qu.IntAll(tmp["is_push"])
 				info["ispanchong"] = 1
 				info["earliestDay"] = qu.IntAll(tmp["earliestDay"])
-				//util.MgoJy.Del(util.JYPushColl, bson.M{"id": info["id"], "isOptimization": info["isOptimization"]})
 				util.MgoJy.Save(util.JYPushColl, info)
 				util.Mgo.UpdateById(source, tmp["_id"], bson.M{"$set": bson.M{"sendflag": true}})
 
@@ -344,8 +347,9 @@ func syncJyData(source, tid, pid string) int {
 			tmp = make(map[string]interface{})
 		}
 		wg.Wait()
-	} else if pid == "676a624edadb2b5c6413bdee" || pid == "676a6230dadb2b5c6413b691" {
-		// 江苏联通 招标/中标
+	} else if pid == "676a624edadb2b5c6413bdee" || pid == "676a6230dadb2b5c6413b691" || pid == "676e01bddadb2b5c6470ffa9" ||
+		pid == "677b52bddadb2b5c64c974c5" {
+		// 江苏联通 招标/中标/运营商
 		q = bson.M{"s_grouptaskid": tid, "is_repeat": 1}
 		query := sess.DB(util.Mgo.DbName).C(source).Find(q).Select(nil).Iter()
 		for tmp := make(map[string]interface{}); query.Next(&tmp); count++ {
@@ -366,6 +370,7 @@ func syncJyData(source, tid, pid string) int {
 				info["ispanchong"] = 1
 				info["earliestDay"] = qu.IntAll(tmp["earliestDay"])
 				//util.MgoJy.Save(util.JYPushColl, info)
+				delete(info, "_id")
 				util.MgoJy.Save("usermail_tmp_js", info)
 				util.Mgo.UpdateById(source, tmp["_id"], bson.M{"$set": bson.M{"sendflag": true}})
 
@@ -907,6 +912,7 @@ func (f *Front) GroupExportData() {
 		}
 		list, _ := util.Mgo.Find(sourceinfo, q, nil, fields, false, -1, -1)
 		for _, l := range *list {
+			id := util.SE.EncodeString(mongodb.BsonIdToSId(l["_id"]))
 			baseinfo := l["v_baseinfo"].(map[string]interface{})
 			if baseinfo["package"] != nil {
 				pkg := baseinfo["package"].(map[string]interface{})
@@ -948,10 +954,14 @@ func (f *Front) GroupExportData() {
 					row.AddCell().SetValue(qu.ObjToString(l["tagname"]))
 					row.AddCell().SetValue(qu.ObjToString(l["tagname2"]))
 					row.AddCell().SetValue(qu.ObjToString(baseinfo["is_effective"]))
+					if l["is_repeat"] != nil {
+						row.AddCell().SetValue(l["is_repeat"])
+					}
+
 				}
 			} else {
 				row := sheet.AddRow()
-				row.AddCell().SetValue(util.SE.EncodeString(qu.ObjToString(l["id"])))
+				row.AddCell().SetValue(id)
 				row.AddCell().SetValue(qu.ObjToString(baseinfo["s_winner"]))
 				row.AddCell().SetValue(qu.ObjToString(baseinfo["buyer"]))
 				row.AddCell().SetValue(qu.ObjToString(baseinfo["projectcode"]))
@@ -971,6 +981,9 @@ func (f *Front) GroupExportData() {
 				row.AddCell().SetValue(qu.ObjToString(l["tagname"]))
 				row.AddCell().SetValue(qu.ObjToString(l["tagname2"]))
 				row.AddCell().SetValue(qu.ObjToString(baseinfo["is_effective"]))
+				if l["is_repeat"] != nil {
+					row.AddCell().SetValue(l["is_repeat"])
+				}
 			}
 		}
 		fname := fmt.Sprintf(modelpath, time.Now().Unix())
@@ -1090,7 +1103,7 @@ func (f *Front) GroupImportData() {
 						if s := qu.ObjToString(baseinfo["s_winner"]); s != "" {
 							update["v_baseinfo.s_winner"] = s + "," + qu.ObjToString(update["v_baseinfo.s_winner"])
 						}
-						update["v_baseinfo.bidamount"] = qu.Float64All(update["v_baseinfo.bidamount"]) + qu.Float64All(baseinfo["bidamount"])
+						update["v_baseinfo.bidamount"] = math.Round(qu.Float64All(update["v_baseinfo.bidamount"]) + qu.Float64All(baseinfo["bidamount"]))
 						c1++
 					}
 				} else {
@@ -1238,3 +1251,151 @@ func countFuc(stype, coll, tid, sctype string) (int, int, int) {
 	}
 	return size, pCount, cCount
 }
+
+func (f *Front) PushRepeatData() {
+	defer qu.Catch()
+	sourceinfo := f.GetString("s_sourceinfo")
+	mf, _, err := f.GetFile("xlsx")
+	if err != nil {
+		f.ServeJson(map[string]interface{}{"success": false, "msg": "数据导入失败"})
+	}
+	binary, _ := io.ReadAll(mf)
+	xls, _ := xlsx.OpenBinary(binary)
+	sheet := xls.Sheets[0]
+	rows := sheet.Rows
+	idcolnum := -1
+	cellFieldName := map[int]string{}
+	count := 0
+	for rn, row := range rows {
+		update := make(map[string]interface{})
+		del := make(map[string]interface{})
+		if rn == 0 {
+			for index, cell := range row.Cells {
+				if cell.Value == "唯一标识" || cell.Value == "信息标识" { //id所在列
+					idcolnum = index
+				}
+				if v := FieldsMap[cell.Value]; v != "" {
+					cellFieldName[index] = v
+				}
+			}
+			if idcolnum == -1 {
+				break
+			}
+			continue
+		} else {
+			id := row.Cells[idcolnum].String()
+			id = util.SE.DecodeString(id)
+			for i, f1 := range cellFieldName {
+				if val := row.Cells[i].Value; val != "" {
+					if f1 == "is_push" || f1 == "is_repeat" || f1 == "earliestDay" {
+						update[f1] = qu.IntAll(val)
+					} else if f1 == "multipackage" {
+						update[fmt.Sprintf("v_baseinfo.%s", f1)] = qu.IntAll(val)
+					} else if f1 == "bidamount" {
+						update[fmt.Sprintf("v_baseinfo.%s", f1)] = qu.Float64All(val)
+					} else {
+						update[fmt.Sprintf("v_baseinfo.%s", f1)] = val
+					}
+				} else {
+					if f1 != "is_push" {
+						del[fmt.Sprintf("v_baseinfo.%s", f1)] = "1"
+					}
+				}
+			}
+			if len(del) > 0 {
+				util.Mgo.UpdateById(sourceinfo, id, bson.M{"$set": update, "$unset": del})
+			} else {
+				util.Mgo.UpdateById(sourceinfo, bson.M{"id": id}, bson.M{"$set": update})
+			}
+
+			tmp, _ := util.Mgo.FindById(sourceinfo, id, nil)
+			if (*tmp)["v_baseinfo"] == nil {
+				qu.Debug("id------", id)
+				return
+			}
+			info := (*tmp)["v_baseinfo"].(map[string]interface{})
+			info["createtime"] = time.Now().Unix()
+			if qu.ObjToString(info["id"]) == "" {
+				info["id"] = id
+			}
+			delete(info, "_id")
+			info["isOptimization"] = qu.IntAll((*tmp)["is_push"])
+			info["ispanchong"] = 1
+			info["earliestDay"] = qu.IntAll((*tmp)["earliestDay"])
+			util.MgoJy.Save("usermail_tmp_js", info)
+			count++
+		}
+	}
+	f.ServeJson(map[string]interface{}{"success": true, "msg": "数据导入成功", "count": count})
+}
+
+func (f *Front) RepeatData() {
+	sourceinfo := f.GetString("s_sourceinfo")
+	groupTaskId := f.GetString("taskid")
+	sess := util.Mgo.GetMgoConn()
+	defer util.Mgo.DestoryMongoConn(sess)
+
+	if crons.Processing {
+		f.ServeJson(map[string]interface{}{"success": false, "msg": "定时任务保存数据中,请稍后执行"})
+	} else {
+		crons.RepeatData()
+		ch := make(chan bool, 5)
+		wg := &sync.WaitGroup{}
+		q := bson.M{"s_grouptaskid": groupTaskId}
+		count := 0
+		query := sess.DB(util.Mgo.DbName).C(sourceinfo).Find(q).Select(nil).Iter()
+		for tmp := make(map[string]interface{}); query.Next(&tmp); count++ {
+			ch <- true
+			wg.Add(1)
+			go func(tmp map[string]interface{}) {
+				defer func() {
+					<-ch
+					wg.Done()
+				}()
+				if getRepeat(tmp) {
+					util.Mgo.UpdateById(sourceinfo, tmp["_id"], bson.M{"$set": bson.M{"is_repeat": 0}})
+				}
+			}(tmp)
+			tmp = make(map[string]interface{})
+		}
+		wg.Wait()
+		f.ServeJson(map[string]interface{}{"success": true, "msg": "数据判重结束"})
+	}
+}
+
+func getRepeat(tmp map[string]interface{}) bool {
+	subtype := qu.ObjToString(tmp["subtype"])
+	pname := qu.ObjToString(tmp["projectname"])
+	pcode := qu.ObjToString(tmp["projectcode"])
+	city := qu.ObjToString(tmp["city"])
+	budget := qu.Float64All(tmp["budget"])
+	bidamount := qu.Float64All(tmp["bidamount"])
+	buyer := qu.ObjToString(tmp["buyer"])
+	winner := qu.ObjToString(tmp["s_winner"])
+
+	key := ""
+	if subtype == "采购意向" {
+		key = fmt.Sprintf(crons.CgKey, subtype, pname, budget, buyer)
+	} else if strings.Contains("招标、邀标、竞价、竞谈、询价", subtype) {
+		key = fmt.Sprintf(crons.ZbKey, subtype, city, pname, budget, buyer)
+	} else if strings.Contains("中标、成交、单一", subtype) {
+		title := qu.ObjToString(tmp["title"])
+		for _, vv := range crons.ItemArr {
+			if strings.Contains(title, vv) {
+				crons.ItemOk = true
+				break
+			}
+		}
+		if crons.ItemOk {
+			key = fmt.Sprintf(crons.ZgbKey, "候选人公式", city, pname, bidamount, pcode, winner, buyer)
+		} else {
+			key = fmt.Sprintf(crons.ZgbKey, "中标通知", city, pname, bidamount, pcode, winner, buyer)
+		}
+	}
+
+	if redis.Get("repeat", key) != nil {
+		return true
+	} else {
+		return false
+	}
+}

+ 8 - 12
src/front/remark.go

@@ -131,12 +131,12 @@ func getDetail(id, coll, stype string, fs []map[string]interface{}) map[string]i
 		bzInfo = make(map[string]interface{})
 	}
 	//baseInfo["detail"] = qu.ObjToString(baseInfo["title"]) + "</br>" + qu.ObjToString(baseInfo["detail"])
-	if contenthtml := qu.ObjToString(baseInfo["contenthtml"]); contenthtml != "" {
-		baseInfo["detail"] = qu.ObjToString(baseInfo["title"]) + "</br>" + contenthtml
-	} else if details := qu.ObjToString(baseInfo["details"]); details != "" {
+	if details := qu.ObjToString(baseInfo["details"]); details != "" {
 		baseInfo["detail"] = qu.ObjToString(baseInfo["title"]) + "</br>" + details
-	} else {
-		baseInfo["detail"] = qu.ObjToString(baseInfo["title"]) + "</br>" + qu.ObjToString(baseInfo["detail"])
+	} else if detail := qu.ObjToString(baseInfo["detail"]); detail != "" {
+		baseInfo["detail"] = qu.ObjToString(baseInfo["title"]) + "</br>" + detail
+	} else if contenthtml := qu.ObjToString(baseInfo["contenthtml"]); contenthtml != "" {
+		baseInfo["detail"] = qu.ObjToString(baseInfo["title"]) + "</br>" + contenthtml
 	}
 	baseInfo["_id"] = mongodb.BsonIdToSId(baseInfo["_id"])
 	purchasingTag, _ := baseInfo["purchasinglist_alltag"].(bool)
@@ -1301,9 +1301,6 @@ func (f *Front) CheckSave() {
 		if len(baseUnsetResult) > 0 {
 			set["$unset"] = baseUnsetResult
 		}
-		qu.Debug(sourceInfo)
-		qu.Debug(infoId)
-		qu.Debug(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})
@@ -1936,9 +1933,6 @@ func (f *Front) JyUserDataMark() {
 		if len(baseUnsetResult) > 0 {
 			set["$unset"] = baseUnsetResult
 		}
-		qu.Debug(sourceInfo)
-		qu.Debug(infoId)
-		qu.Debug(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})
@@ -2453,7 +2447,9 @@ func MarkPackage(content []interface{}, tagSet, baseSet, baseUnset map[string]in
 		if len(pkgs) > 0 {
 			baseSet["package"] = pkgs
 			baseSet["s_winner"] = strings.Join(sw, ",")
-			baseSet["bidamount"] = total
+			delete(baseUnset, "s_winner")
+			baseSet["bidamount"] = math.Round(total)
+			delete(baseUnset, "bidamount")
 		} else if len(content) == 0 { //只有删除
 			baseUnset["package"] = ""
 			baseSet["multipackage"] = 0

+ 6 - 5
src/go.mod

@@ -21,9 +21,7 @@ require (
 	github.com/andybalholm/cascadia v1.3.1 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/garyburd/redigo v1.6.2 // indirect
-	github.com/go-xweb/httpsession v0.0.0-20141220075701-356d3b4d38d6 // indirect
-	github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e // indirect
-	github.com/go-xweb/uuid v0.0.0-20140604020037-d7dce341f851 // indirect
+	github.com/go-sql-driver/mysql v1.6.0 // indirect
 	github.com/gogf/gf/v2 v2.7.0 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gomodule/redigo v1.8.9 // indirect
@@ -31,10 +29,9 @@ require (
 	github.com/howeyc/fsnotify v0.9.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/klauspost/compress v1.16.7 // indirect
-	github.com/lunny/csession v0.0.0-20130910075847-fe53c5de3dfd // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
-	github.com/mattn/go-sqlite3 v1.14.27 // indirect
 	github.com/montanaflynn/stats v0.7.1 // indirect
+	github.com/nsqio/go-nsq v1.1.0 // indirect
 	github.com/olivere/elastic/v7 v7.0.32 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/vcaesar/cedar v0.20.2 // indirect
@@ -44,10 +41,14 @@ require (
 	github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
 	go.opentelemetry.io/otel v1.14.0 // indirect
 	go.opentelemetry.io/otel/trace v1.14.0 // indirect
+	go.uber.org/atomic v1.7.0 // indirect
+	go.uber.org/multierr v1.6.0 // indirect
+	go.uber.org/zap v1.22.0 // indirect
 	golang.org/x/crypto v0.26.0 // indirect
 	golang.org/x/net v0.21.0 // indirect
 	golang.org/x/sync v0.12.0 // indirect
 	golang.org/x/sys v0.23.0 // indirect
 	golang.org/x/time v0.11.0 // indirect
 	gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
+	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 )

+ 8 - 13
src/go.sum

@@ -29,7 +29,6 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
 github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
-github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
 github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
 github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
@@ -42,15 +41,8 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
 github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
 github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-xweb/httpsession v0.0.0-20141220075701-356d3b4d38d6 h1:DUiWdm3rS8cC96Y0XeVkDeizzEK6X+qiNgXytLVtbkM=
-github.com/go-xweb/httpsession v0.0.0-20141220075701-356d3b4d38d6/go.mod h1:lwPk13GS+i/NK4FkMm68IcJrAwiu+HtjYa1Y4kW59aY=
-github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e h1:xmffs7hgrWpAOcquZrdlWpAEaAdlI9myaYcUUmhIP7k=
-github.com/go-xweb/log v0.0.0-20140701090824-270d183ad77e/go.mod h1:ASmYUSBf32lWkkNVX/pnOU4MLuUQpFH4qYHvWHt/l0w=
-github.com/go-xweb/uuid v0.0.0-20140604020037-d7dce341f851 h1:D46USD6oGNWzoJ/h5CWaFq3ELLoLoJzllJ03Xh78VYg=
-github.com/go-xweb/uuid v0.0.0-20140604020037-d7dce341f851/go.mod h1:OmDEC58ZYO1Esk+Uy32SB6LWof9lyROl7q76dBFOCWw=
-github.com/go-xweb/xweb v0.2.1 h1:u5t/ttuSfxiIMDTXj/Pouw9C2ASNABWT16JWHyrtdvY=
-github.com/go-xweb/xweb v0.2.1/go.mod h1:vPjYJgfidYAgBKIwiAyKFC1hfczlqsw9rRT8LtwrGew=
 github.com/gogf/gf/v2 v2.7.0 h1:CjxhbMiE7oqf6K8ZtGuKt3dQEwK4vL6LhiI+dI7tJGU=
 github.com/gogf/gf/v2 v2.7.0/go.mod h1:Qu8nimKt9aupJQcdUL85tWF4Mfxocz97zUt8UC4abVI=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -106,8 +98,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/lunny/csession v0.0.0-20130910075847-fe53c5de3dfd h1:DXxmBCahjva4Ox4AWOv6pR1Csv33zSj97SaLOElfIsw=
-github.com/lunny/csession v0.0.0-20130910075847-fe53c5de3dfd/go.mod h1:3w9PScemEkJoLw3OYvLWMoD8XRCmXgGwsSpT6pFpJ0g=
 github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
 github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
@@ -118,14 +108,14 @@ github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPn
 github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
-github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU=
-github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
 github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
+github.com/nsqio/go-nsq v1.1.0 h1:PQg+xxiUjA7V+TLdXw7nVrJ5Jbl3sN86EhGCQj4+FYE=
 github.com/nsqio/go-nsq v1.1.0/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQTuDEY=
 github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/olivere/elastic v6.2.37+incompatible h1:UfSGJem5czY+x/LqxgeCBgjDn6St+z8OnsCuxwD3L0U=
 github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=
 github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k=
 github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
@@ -180,9 +170,12 @@ go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDs
 go.opentelemetry.io/otel/trace v1.5.0/go.mod h1:sq55kfhjXYr1zVSyexg0w1mpa03AYXR5eyTkB9NPPdE=
 go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
 go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
+go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
+go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
 go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/zap v1.22.0 h1:Zcye5DUgBloQ9BaT4qc9BnjOFog5TvBSAGkJ3Nf70c0=
 go.uber.org/zap v1.22.0/go.mod h1:H4siCOZOrAolnUPJEkfaSjDqyP+BDS0DdDWzwcgt3+U=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -284,6 +277,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
 gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

+ 5 - 0
src/util/config.go

@@ -41,6 +41,8 @@ var (
 	FieldsArr           []map[string]interface{}
 	MgoHM               *mongodb.MongodbSim //高质量库
 
+	CreateTime int64
+
 	MgoBulkSize = 200
 )
 
@@ -174,6 +176,9 @@ func InitConfig() {
 		CustomerFieldMap_EH[val] = k
 	}
 
+	CreateTime = 0
+	redis.InitRedis(qu.ObjToString(Sysconfig["redis"]))
+
 	//公告类型
 	types := Sysconfig["topsubtype"].(map[string]interface{})
 	for top, v := range types {

+ 58 - 1
src/web/templates/project/project_clear.html

@@ -97,6 +97,11 @@
                                         <label class="form-inline" style="margin-left: 5px">已验收:
                                             <input type="text" class="form-control" style="width: 80px" readonly value="{{.T.acceptNum}}"></label>
                                     </div>
+                                    <div class="col-xs-5 form-group">
+                                        <label class="form-inline">操作:
+                                            <a type="button" class="btn btn-sm btn-primary" onclick="importRepeatData()">重复补推</a>
+                                        </label>
+                                    </div>
                                 </div>
                             </div>
                         </div>
@@ -277,13 +282,18 @@
                                 tmp = '<div>' +
                                     '<a class="btn btn-sm btn-primary" href="/front/group/user/task/list?pid='+projectid+'&grouptaskid='+val+'&s_groupid='+row.s_groupid+'&s_sourceinfo='+row.s_sourceinfo+'">查看</a>&nbsp;&nbsp;' +
                                     '<a class="btn btn-sm btn-primary" onclick="checkMethod1(\'' + row.s_projectid + '\',\'' + val + '\',\'' + row.s_sourceinfo + '\')">质检</a>&nbsp;&nbsp;' +
+                                    '<a class="btn btn-sm btn-primary" onclick="repeatMethod(\'' + val + '\')">判重</a>&nbsp;&nbsp;' +
                                     '<a class="btn btn-sm btn-primary" onclick="syncJyCm(\'' + val + '\',\''+row.s_sourceinfo+'\',\'' + row.s_status + '\')">推送</a>&nbsp;&nbsp;' +
                                     '<a class="btn btn-sm btn-primary" onclick="exportData(\'' + val + '\',\''+row.s_sourceinfo+'\')">导出</a>&nbsp;&nbsp;' +
                                     '<a class="btn btn-sm btn-primary" onclick="importData(\'' + val + '\',\''+row.s_sourceinfo+'\')">导入</a>&nbsp;&nbsp;' +
                                     '<a class="btn btn-sm btn-primary" onclick="StatsTask(\'' + val + '\',\'' + row.s_status + '\',\''+row.s_sourceinfo+'\')">信息统计</a>&nbsp;&nbsp;' +
                                     '</div>';
                             }
-                        }else {
+                        } else if (row.s_status === '已关闭') {
+                            tmp = '<div>' +
+                                '<a class="btn btn-sm btn-primary" href="/front/group/user/task/list?pid='+projectid+'&grouptaskid='+val+'&s_groupid='+row.s_groupid+'&s_sourceinfo='+row.s_sourceinfo+'">查看</a>&nbsp;&nbsp;' +
+                                '</div>';
+                        } else {
                             tmp = '<div>' +
                                 '<a class="btn btn-sm btn-primary" href="/front/group/user/task/list?pid='+projectid+'&grouptaskid='+val+'&s_groupid='+row.s_groupid+'&s_sourceinfo='+row.s_sourceinfo+'">查看</a>&nbsp;&nbsp;' +
                                 '<a class="btn btn-sm btn-primary" onclick="retrieveTask(\''+val+'\',\''+row.s_sourceinfo+'\',\''+row.s_status+'\')">收回</a>&nbsp;&nbsp;' +
@@ -609,6 +619,53 @@
         $(input).click();
     }
 
+    function importRepeatData() {
+        let input = $("<input>").attr("type", "file").hide();
+        $(input).on("change", function() {
+            showLoading("正在导入数据,请稍候...")
+            let file = this.files[0];
+            // 创建FormData对象,用于上传文件
+            let formData = new FormData();
+            formData.append("s_sourceinfo", sourceinfo)
+            formData.append("xlsx", file);
+            $.ajax({
+                url: "/front/push/repeat/data",
+                type: "POST",
+                data: formData,
+                processData: false,
+                contentType: false,
+                success: function(r) {
+                    hideLoading()
+                    if (r.success) {
+                        showTip("导入数据成功,一共导入"+r.count+"条数据", 4000);
+                    }
+                },
+                error: function(xhr, status, error) {
+                    hideLoading()
+                    showMsg(error);
+                }
+            });
+        });
+        $(input).click();
+    }
+
+    function repeatMethod(id) {
+        showLoading("正在数据判重...")
+        $.ajax({
+            url: "/front/repeat/repeat/data",
+            type: 'POST',
+            data: { "s_sourceinfo": sourceinfo, "taskid": id},
+            success: function (r) {
+                if (r.success) {
+                    hideLoading()
+                    showTip(r.msg)
+                } else {
+                    showTip(r.msg);
+                }
+            }
+        })
+    }
+
     function checkMethod(stype) {
         // if (stype === "all") {
         //     if (num2 <= 0) {