package main import ( "encoding/json" "github.com/go-xweb/log" "github.com/goinggo/mapstructure" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "math" mu "mfw/util" qu "qfw/util" "reflect" "sort" "strings" "time" ) /** 直接修改保存项目字段信息 */ func (p *ProjectTask) modifyUpdate(pid string, index, position int, tmpPro, modifyProMap map[string]interface{}) { // 1-0 备份 tmpPro["reason"] = "直接在原有项目上修改字段信息" backupPro(tmpPro) delete(tmpPro, "reason") // 1-1 修改字段信息 updateSet := UpdateValue(tmpPro, index, position, modifyProMap) updateSet["list"] = tmpPro["list"] // 1-2 修改mgo bol := MongoTool.UpdateById(ProjectColl, pid, map[string]interface{}{"$set": updateSet}) if bol { // 1-3 修改es by, _ := json.Marshal(map[string]interface{}{ "query": map[string]interface{}{ "_id": bson.M{ "$gte": pid, "$lte": pid, }}, "stype": "project", }) qu.Debug(string(by)) _ = udpclient.WriteUdp(by, mu.OP_TYPE_DATA, toaddr[1]) } // 修改内存 p.modifyMem(tmpPro) } func (p *ProjectTask) mergeAndModify(pInfoId string, index, position int, tmp map[string]interface{}, tmpPro map[string]interface{}, modifyMap map[string]interface{}) { proList := []interface{}(tmpPro["list"].(primitive.A)) info := ParseInfo(tmp) //项目中list大小等于1 if len(proList) == 1 { log.Println("list大小等于1 合并", "------1------") // 2.1 重新合并 merge := p.ReMerge(info, tmp, tmpPro) if merge { //合并到新项目中 //删除老项目 p.AllIdsMapLock.Lock() delete(p.AllIdsMap, pInfoId) p.AllIdsMapLock.Unlock() delOldPro(pInfoId) // 2.2 备份 tmpPro["reason"] = "删除原有项目,修改合并到新的项目中" backupPro(tmpPro) } else { //没有合并到新项目中 p.modifyUpdate(pInfoId, index, position, tmpPro, modifyMap) // 修改内存 p.modifyMem(tmpPro) } }else if index == 0 { // 招标公告信息在原有项目中位于第1个 merge := p.ReMerge(info, tmp, tmpPro) if merge { // 合并到新项目中 // 该条招标公告信息重新参与合并,该项目的其它招标公告信息逐条参与合并 tmpPro["reason"] = "修改list中第一个条招标公告信息" backupPro(tmpPro) delete(tmpPro, "reason") proList = deleteSlice1(proList, proList[0]) p.AllIdsMapLock.Lock() Id := p.AllIdsMap[pInfoId] p.AllIdsMapLock.Unlock() proMem := Id.P flag := true // 标记是否需要删除原有项目信息 for _, v := range proList{ v1 := v.(map[string]interface{}) temp := MongoTool.FindById(ExtractColl, qu.ObjToString(v1["infoid"])) if len(temp) == 0 { temp = MongoTool.FindById(ExtractColl1, qu.ObjToString(v1["infoid"])) if len(temp) == 0 { qu.Debug("extract not find id...", v1["infoid"]) continue } } tempInfo := ParseInfo(temp) if flag { merge := p.ReMerge(tempInfo, temp, tmpPro) if !merge { flag = false break } } } if flag { delOldPro(pInfoId) }else { //合并到原有项目中, 不用继续重新合并, 原有项目内部合并即可 p.innerMerge(proList, tmpPro) bol := MongoTool.UpdateById(ProjectColl, pInfoId, map[string]interface{}{"$set": tmpPro}) if bol { by, _ := json.Marshal(map[string]interface{}{ "query": map[string]interface{}{ "_id": bson.M{ "$gte": pInfoId, "$lte": pInfoId, }}, "stype": "project", }) qu.Debug(string(by)) _ = udpclient.WriteUdp(by, mu.OP_TYPE_DATA, toaddr[1]) } // 修改内存 p.AllIdsMapLock.Lock() if v, ok := p.AllIdsMap[pInfoId]; ok { v.P = proMem } p.AllIdsMapLock.Unlock() } }else { //没有合并到新项目中,更新list字段,有条件更新项目外围字段 p.modifyUpdate(pInfoId, index, position, tmpPro, modifyMap) // 修改内存 p.modifyMem(tmpPro) } }else if index == 1 { // 招标公告信息在原有项目中处于中间某一条 merge := p.ReMerge(info, tmp, tmpPro) if merge { tmpPro["reason"] = "修改list中位于中间某一条招标公告信息" backupPro(tmpPro) delete(tmpPro, "reason") p.innerMerge1(proList, qu.ObjToString(tmp["infoid"]), tmpPro) bol := MongoTool.UpdateById(ProjectColl, pInfoId, map[string]interface{}{"$set": tmpPro}) if bol { by, _ := json.Marshal(map[string]interface{}{ "query": map[string]interface{}{ "_id": bson.M{ "$gte": pInfoId, "$lte": pInfoId, }}, "stype": "project", }) qu.Debug(string(by)) _ = udpclient.WriteUdp(by, mu.OP_TYPE_DATA, toaddr[1]) } }else { // 未合并到新项目中 p.modifyUpdate(pInfoId, index, position, tmpPro, modifyMap) // 修改内存 p.modifyMem(tmpPro) } }else if index == 2 { // 招标公告信息在原有项目中位于最后一条 merge := p.ReMerge(info, tmp, tmpPro) if merge { // 合并到新项目中 tmpPro["reason"] = "修改list中最后一条招标公告信息" backupPro(tmpPro) w := len(proList) - 1 proList = deleteSlice1(proList, proList[w]) p.innerMerge(proList, tmpPro) bol := MongoTool.UpdateById(ProjectColl, pInfoId, map[string]interface{}{"$set": tmpPro}) if bol { by, _ := json.Marshal(map[string]interface{}{ "query": map[string]interface{}{ "_id": bson.M{ "$gte": pInfoId, "$lte": pInfoId, }}, "stype": "project", }) qu.Debug(string(by)) _ = udpclient.WriteUdp(by, mu.OP_TYPE_DATA, toaddr[1]) } }else { // 未合并到新项目中 p.modifyUpdate(pInfoId, index, position, tmpPro, modifyMap) // 修改内存 p.modifyMem(tmpPro) } } } // 删除 func (p *ProjectTask) delJudge(infoid, pid string) { tmpPro := MongoTool.FindById(ProjectColl, pid) ids := []interface{}(tmpPro["ids"].(primitive.A)) proList := []interface{}(tmpPro["list"].(primitive.A)) if len(ids) == 1 { tmpPro["reason"] = "删除项目信息" backupPro(tmpPro) c := MongoTool.Delete(ProjectColl, pid) if c > 0 { client := Es.GetEsConn() defer Es.DestoryEsConn(client) Es.DelById(Itype, Index, pid) } return } var index = -1 //0:第一个,1:中间,2:最后一个 for i, v := range ids { if qu.ObjToString(v) == infoid { if i == 0 { index = 0 }else if i == len(ids) - 1 { index = 2 }else { index = 1 } } } if index == 0 { tmpPro["reason"] = "删除list中第一个条招标公告信息" backupPro(tmpPro) delete(tmpPro, "reason") proList = deleteSlice1(proList, proList[0]) var pro *ProjectInfo flag := true // 标记是否需要删除原有项目信息 for _, v := range proList{ v1 := v.(map[string]interface{}) temp := MongoTool.FindById(ExtractColl, qu.ObjToString(v1["infoid"])) if len(temp) == 0 { temp = MongoTool.FindById(ExtractColl1, qu.ObjToString(v1["infoid"])) if len(temp) == 0 { qu.Debug("extract not find id...", v1["infoid"]) continue } } tempInfo := ParseInfo(temp) if flag { merge := p.ReMerge(tempInfo, temp, tmpPro) if !merge { flag = false break } } } if flag { delOldPro(pid) }else { tmpPro, pro = p.innerMerge(proList, tmpPro) bol := MongoTool.UpdateById(ProjectColl, pid, map[string]interface{}{"$set": tmpPro}) if bol { by, _ := json.Marshal(map[string]interface{}{ "query": map[string]interface{}{ "_id": bson.M{ "$gte": pid, "$lte": pid, }}, "stype": "project", }) qu.Debug(string(by)) _ = udpclient.WriteUdp(by, mu.OP_TYPE_DATA, toaddr[1]) } // 修改内存 p.AllIdsMapLock.Lock() if v, ok := p.AllIdsMap[pid]; ok { v.P = pro } p.AllIdsMapLock.Unlock() } }else if index == 1 { tmpPro["reason"] = "删除list中间某一条招标公告信息" backupPro(tmpPro) delete(tmpPro, "reason") var pro *ProjectInfo tmpPro, pro = p.innerMerge1(proList, infoid, tmpPro) bol := MongoTool.UpdateById(ProjectColl, pid, map[string]interface{}{"$set": tmpPro}) if bol { by, _ := json.Marshal(map[string]interface{}{ "query": map[string]interface{}{ "_id": bson.M{ "$gte": pid, "$lte": pid, }}, "stype": "project", }) qu.Debug(string(by)) _ = udpclient.WriteUdp(by, mu.OP_TYPE_DATA, toaddr[1]) } // 内存 p.AllIdsMapLock.Lock() if v, ok := p.AllIdsMap[pid]; ok { v.P = pro } p.AllIdsMapLock.Unlock() }else if index == 2 { tmpPro["reason"] = "删除list中最后一条招标公告信息" backupPro(tmpPro) delete(tmpPro, "reason") w := len(proList) - 1 proList = deleteSlice1(proList, proList[w]) var pro *ProjectInfo tmpPro, pro = p.innerMerge(proList, tmpPro) bol := MongoTool.UpdateById(ProjectColl, pid, map[string]interface{}{"$set": tmpPro}) if bol { by, _ := json.Marshal(map[string]interface{}{ "query": map[string]interface{}{ "_id": bson.M{ "$gte": pid, "$lte": pid, }}, "stype": "project", }) qu.Debug(string(by)) _ = udpclient.WriteUdp(by, mu.OP_TYPE_DATA, toaddr[1]) } // 内存 p.AllIdsMapLock.Lock() if v, ok := p.AllIdsMap[pid]; ok { v.P = pro } p.AllIdsMapLock.Unlock() } } // 合并 func (p *ProjectTask) ReMerge(info *Info, tmp map[string]interface{}, tmpPro map[string]interface{}) bool { bpn, bpc, bptc, bpb, pids, _, IDArr := p.getCompareIds(info.ProjectName, info.ProjectCode, info.PTC, info.Buyer) defer p.wg.Done() for _, m := range pids { defer m.Lock.Unlock() } for _, id := range IDArr { defer id.Lock.Unlock() } bFindProject := false findPid := "" comRes1 := []*ProjectInfo{} comRes2 := []*ProjectInfo{} comRes3 := []*ProjectInfo{} for _, v := range IDArr { comStr := "" compareProject := v.P compareProject.score = 0 diffTime := int64(math.Abs(float64(info.Publishtime - compareProject.LastTime))) if diffTime <= p.validTime { if CheckContain(compareProject.Agency, info.Agency) == 3 { continue } if ComparePlace(compareProject, info) { continue } info.PNBH = 0 info.PCBH = 0 info.PTCBH = 0 compareStr, score := comparePNC(info, compareProject) resVal, pjVal := Select(compareStr, info, compareProject) if resVal > 0 { compareBuyer, compareCity, compareTime, compareAgency, compareBudget, compareBidmount, score2 := p.compareBCTABB(info, compareProject, diffTime, score) comStr = compareStr + compareBuyer + compareCity + compareTime + compareAgency + compareBudget + compareBidmount compareProject.comStr = comStr compareProject.pjVal = pjVal compareProject.resVal = resVal eqV := compareResult(resVal, pjVal, score2, comStr, compareBuyer, compareCity, compareTime, compareAgency, compareBudget, compareBidmount) if eqV == 1 { comRes1 = append(comRes1, compareProject) } else if eqV == 2 { comRes2 = append(comRes2, compareProject) } else if eqV == 3 { comRes3 = append(comRes3, compareProject) } } } } //--------------------------------对比完成----------------------- for kv, resN := range [][]*ProjectInfo{comRes1, comRes2, comRes3} { if len(resN) > 0 { if len(resN) > 1 { sort.Slice(resN, func(i, j int) bool { return resN[i].score > resN[j].score }) } ex := 0 resArr := []*ProjectInfo{} for i, res := range resN { choose, e := p.CompareStatus(resN[i], info) if !choose { ex = e resArr = append(resArr, res) } } if len(resArr) > 0 { bFindProject = true findPid = resArr[0].Id.Hex() if findPid == BsonIdToSId(tmpPro["_id"]) { return false } p.updateProFiled(tmp, info, resArr[0], kv+1, resArr[0].comStr, ex) for k2, bv := range []int{bpn, bpc, bptc, bpb} { if bv > -1 { pids[bv].Arr = append(pids[bv].Arr, findPid) if k2 == 0 { if resArr[0].ProjectName == "" { resArr[0].ProjectName = info.ProjectName } else { if resArr[0].MPN == nil { resArr[0].MPN = []string{info.ProjectName} } else { resArr[0].MPN = append(resArr[0].MPN, info.ProjectName) } } } else if k2 < 3 { if resArr[0].ProjectCode == "" { resArr[0].ProjectCode = qu.If(k2 == 1, info.ProjectCode, info.PTC).(string) } else { if resArr[0].MPC == nil { resArr[0].MPC = []string{qu.If(k2 == 1, info.ProjectCode, info.PTC).(string)} } else { resArr[0].MPC = append(resArr[0].MPC, qu.If(k2 == 1, info.ProjectCode, info.PTC).(string)) } } } else { if resArr[0].Buyer == "" { resArr[0].Buyer = info.Buyer } } } } } else { bFindProject = false findPid = "" } break } } if !bFindProject { id, p1 := p.NewProject(tmp, info) p.AllIdsMapLock.Lock() p.AllIdsMap[id] = &ID{Id: id, P: p1} p.AllIdsMapLock.Unlock() for _, m := range pids { m.Arr = append(m.Arr, id) } return false } return true } //内部合并 func (p *ProjectTask) innerMerge(infoList []interface{}, tmpPro map[string]interface{}) (map[string]interface{}, *ProjectInfo) { newP := make(map[string]interface{}) newP["_id"] = tmpPro["_id"] var p1 *ProjectInfo for k, m := range infoList{ m1 := m.(map[string]interface{}) temp := MongoTool.FindById(ExtractColl, qu.ObjToString(m1["infoid"])) if len(temp) == 0 { temp = MongoTool.FindById(ExtractColl1, qu.ObjToString(m1["infoid"])) if len(temp) == 0 { qu.Debug("extract not find id...", m1["infoid"]) continue } } tempInfo := ParseInfo(temp) if k == 0 { p1 = p.newPro(temp, newP, tempInfo) }else { p.updateOldProField(p1, tempInfo, newP, temp, m1) } } return newP, p1 } func (p *ProjectTask) innerMerge1(infoList []interface{}, infoid string, tmpPro map[string]interface{}) (map[string]interface{}, *ProjectInfo) { newP := make(map[string]interface{}) newP["_id"] = tmpPro["_id"] var p1 *ProjectInfo for k, m := range infoList{ m1 := m.(map[string]interface{}) if m1["infoid"] == infoid { continue } temp := MongoTool.FindById(ExtractColl, qu.ObjToString(m1["infoid"])) if len(temp) == 0 { temp = MongoTool.FindById(ExtractColl1, qu.ObjToString(m1["infoid"])) if len(temp) == 0 { qu.Debug("extract not find id...", m1["infoid"]) continue } } tempInfo := ParseInfo(temp) if k == 0 { p1 = p.newPro(temp, newP, tempInfo) }else { p.updateOldProField(p1, tempInfo, newP, temp, m1) } } return newP, p1 } // 更新招标公告到新的项目中 func (p *ProjectTask) updateProFiled(tmp map[string]interface{}, thisinfo *Info, pInfo *ProjectInfo, weight int, comStr string, ex int) { set := map[string]interface{}{} pInfo.Ids = append(pInfo.Ids, thisinfo.Id) if len(pInfo.Ids) > 30 { //异常标记 set["listtag"] = 1 } if thisinfo.Publishtime > pInfo.LastTime { pInfo.LastTime = thisinfo.Publishtime set["lasttime"] = thisinfo.Publishtime } if thisinfo.TopType == "招标" { if thisinfo.SubType != "变更" && thisinfo.SubType != "其它" && pInfo.Zbtime <= 0 { set["zbtime"] = tmp["publishtime"] } } else if thisinfo.TopType == "结果" { if thisinfo.SubType == "中标" || thisinfo.SubType == "成交" || thisinfo.SubType == "流标" || thisinfo.SubType == "废标" { if pInfo.Jgtime > 0 { jg1 := int64(math.Abs(float64(pInfo.Jgtime - thisinfo.Publishtime))) //公告状态和项目状态同样都是中标或者成交, if (thisinfo.SubType == "中标" || thisinfo.SubType == "成交") && (pInfo.Bidstatus == "中标" || pInfo.Bidstatus == "成交") { if jg1 > p.jgTime { set["jgtime"] = tmp["publishtime"] pInfo.Jgtime = thisinfo.Publishtime } } else if (thisinfo.SubType == "流标" || thisinfo.SubType == "废标") && (pInfo.Bidstatus == "流标" || pInfo.Bidstatus == "废标") { //公告状态和项目状态同样是流标或者废标 if jg1 > p.jgTime { set["jgtime"] = tmp["publishtime"] pInfo.Jgtime = thisinfo.Publishtime } } } else { set["jgtime"] = tmp["publishtime"] pInfo.Jgtime = thisinfo.Publishtime } } } else if thisinfo.SubType == "合同" { if pInfo.Bidstatus == "中标" || pInfo.Bidstatus == "成交" || pInfo.Bidstatus == "" { //中标、成交不更新jgtime } else { set["jgtime"] = tmp["publishtime"] pInfo.Jgtime = thisinfo.Publishtime } } if thisinfo.Bidopentime > pInfo.Bidopentime { pInfo.Bidopentime = thisinfo.Bidopentime set["bidopentime"] = pInfo.Bidopentime } // bidtype、bidstatus pInfo.Bidtype, pInfo.Bidstatus = p.GetBidTypeAndBidStatus(thisinfo) set["bidtype"] = pInfo.Bidtype set["bidstatus"] = pInfo.Bidstatus //异常标记 if ex > 0 { set["exception"] = ex } //相同城市的公告才会合并到一起(全国列外) if thisinfo.Area != "全国" { pInfo.Area = thisinfo.Area set["area"] = thisinfo.Area pInfo.City = thisinfo.City set["city"] = thisinfo.City if thisinfo.District != "" { pInfo.District = thisinfo.District set["district"] = thisinfo.District } } // 项目名称 if (thisinfo.ProjectName != "" && pInfo.ProjectName == "") || (len([]rune(pInfo.ProjectName)) < 6 && thisinfo.LenPN > 6) { pInfo.ProjectName = thisinfo.ProjectName set["projectname"] = thisinfo.ProjectName } // 项目编号 if (pInfo.ProjectCode == "" && thisinfo.ProjectCode != "") || (len([]rune(pInfo.ProjectCode)) < 6 && len([]rune(thisinfo.ProjectCode)) > 6) { pInfo.ProjectCode = thisinfo.ProjectCode set["projectcode"] = thisinfo.ProjectCode } // 采购单位 if (pInfo.Buyer == "" && thisinfo.Buyer != "") || (len([]rune(pInfo.Buyer)) < 5 && len([]rune(thisinfo.Buyer)) > 5) { pInfo.Buyer = thisinfo.Buyer set["buyer"] = thisinfo.Buyer pInfo.Buyerclass = thisinfo.Buyerclass set["buyerclass"] = thisinfo.Buyerclass } if pInfo.Buyer == "" { set["buyerclass"] = "" } // 采购单位联系人 if thisinfo.Buyerperson != "" { pInfo.Buyerperson = thisinfo.Buyerperson set["buyerperson"] = pInfo.Buyerperson } else { pInfo.Buyerperson = "" set["buyerperson"] = "" } // 采购单位電話 if thisinfo.Buyertel != "" { pInfo.Buyertel = thisinfo.Buyertel set["buyertel"] = pInfo.Buyertel } else { pInfo.Buyertel = "" set["buyertel"] = "" } if thisinfo.ContractCode != "" { set["contractcode"] = pInfo.ContractCode + "," + thisinfo.ContractCode } // 代理机构 相同的代理机构才会合并到一个项目 2020.11.9 //if (pInfo.Agency == "" && thisinfo.Agency != "") || (len([]rune(pInfo.Agency)) < 5 && len([]rune(thisinfo.Agency)) > 5) { // pInfo.Agency = thisinfo.Agency // set["agency"] = thisinfo.Agency //} if len(thisinfo.Topscopeclass) > 0 && thisinfo.Publishtime > pInfo.LastTime { sort.Strings(pInfo.Topscopeclass) for _, k := range thisinfo.Topscopeclass { if BinarySearch(pInfo.Topscopeclass, k) == -1 { pInfo.Topscopeclass = append(pInfo.Topscopeclass, k) sort.Strings(pInfo.Topscopeclass) } } set["topscopeclass"] = pInfo.Topscopeclass } // 项目评审专家 if len(thisinfo.ReviewExperts) > 0 && thisinfo.Publishtime > pInfo.LastTime { set["review_experts"] = thisinfo.ReviewExperts pInfo.ReviewExperts = thisinfo.ReviewExperts } if thisinfo.Purchasing != "" && thisinfo.Publishtime > pInfo.LastTime { if pInfo.Purchasing == "" { pInfo.Purchasing = thisinfo.Purchasing set["purchasing"] = thisinfo.Purchasing } else { list := strings.Split(pInfo.Purchasing, ",") for _, k := range list { if BinarySearch(strings.Split(thisinfo.Purchasing, ","), k) == -1 { list = append(list, k) sort.Strings(list) } } set["purchasing"] = strings.Join(list, ",") } } //中标候选人 if len(thisinfo.WinnerOrder) > 0 && thisinfo.Publishtime > pInfo.LastTime { var list = []string{} for _, v := range thisinfo.WinnerOrder { if BinarySearch(list, qu.ObjToString(v["entname"])) == -1 { list = append(list, qu.ObjToString(v["entname"])) } } set["winnerorder"] = list pInfo.Winnerorder = list } if len(thisinfo.Subscopeclass) > 0 && thisinfo.Publishtime > pInfo.LastTime { sort.Strings(pInfo.Subscopeclass) for _, k := range thisinfo.Subscopeclass { if BinarySearch(pInfo.Subscopeclass, k) == -1 { pInfo.Subscopeclass = append(pInfo.Subscopeclass, k) sort.Strings(pInfo.Subscopeclass) } } set["subscopeclass"] = pInfo.Subscopeclass set["s_subscopeclass"] = strings.Join(pInfo.Subscopeclass, ",") } if len(thisinfo.Winners) > 0 && thisinfo.Publishtime > pInfo.LastTime { if len(pInfo.Winners) <= 0 { set["winner"] = qu.ObjToString(tmp["winner"]) } sort.Strings(pInfo.Winners) for _, k := range thisinfo.Winners { if thisinfo.SubType == "流标" || thisinfo.SubType == "废标" { if BinarySearch(pInfo.Winners, k) != -1 { deleteSlice(pInfo.Winners, k, "") sort.Strings(pInfo.Winners) } } else { if BinarySearch(pInfo.Winners, k) == -1 { pInfo.Winners = append(pInfo.Winners, k) sort.Strings(pInfo.Winners) } } } set["s_winner"] = strings.Join(pInfo.Winners, ",") } if thisinfo.HasPackage { //多包处理 set["multipackage"] = 1 pkg := PackageFormat(thisinfo, pInfo) pInfo.Package = pkg set["package"] = pInfo.Package } //处理多包后,计算预算金额、中标金额 CountAmount(pInfo, thisinfo, tmp) if pInfo.Budget >= 0 && pInfo.Budgettag != 1 { set["budget"] = pInfo.Budget set["budgettag"] = 0 } if pInfo.Bidamount >= 0 && pInfo.Bidamounttag != 1 { set["bidamount"] = pInfo.Bidamount set["bidamounttag"] = 0 } if pInfo.Bidamount >= pInfo.Budget { set["sortprice"] = pInfo.Bidamount } else if pInfo.Budget >= pInfo.Bidamount { set["sortprice"] = pInfo.Budget } infofield := InfoField{ Budget: thisinfo.Budget, Bidamount: thisinfo.Bidamount, ContractCode: thisinfo.ContractCode, ProjectName: thisinfo.ProjectName, ProjectCode: thisinfo.ProjectCode, Bidstatus: pInfo.Bidstatus, } copyMap := Copy(pInfo.InfoFiled).(map[string]InfoField) copyMap[thisinfo.Id] = infofield tmpMap := make(map[string]interface{}) for k, v := range copyMap { tmpMap[k] = StructToMap(v) } tmpMap[thisinfo.Id] = StructToMap(infofield) pInfo.InfoFiled = copyMap set["infofield"] = tmpMap set["mpn"] = pInfo.MPN set["mpc"] = pInfo.MPC set["updatetime"] = p.pici update := map[string]interface{}{} if len(set) > 0 { update["$set"] = set } push := p.PushListInfo(tmp, thisinfo.Id) push["s_winner"] = strings.Join(thisinfo.Winners, ",") push["compareStr"] = comStr push["resVal"] = pInfo.resVal push["pjVal"] = pInfo.pjVal update["$push"] = map[string]interface{}{ "list": push, "ids": thisinfo.Id, } bol := MongoTool.UpdateById(ProjectColl, pInfo.Id.Hex(), update) if bol { by, _ := json.Marshal(map[string]interface{}{ "query": map[string]interface{}{ "_id": bson.M{ "$gte": pInfo.Id.Hex(), "$lte": pInfo.Id.Hex(), }}, "stype": "project", }) qu.Debug(string(by)) _ = udpclient.WriteUdp(by, mu.OP_TYPE_DATA, toaddr[1]) } } // 内部合并时,原有项目id基础上新建项目 func (p *ProjectTask) newPro(tmp, tmpPro map[string]interface{}, thisinfo *Info) *ProjectInfo { for _, f := range FIELDS { if tmp[f] != nil && tmp[f] != "" { tmpPro[f] = tmp[f] } } bidopentime := qu.Int64All(tmp["bidopentime"]) if bidopentime > 0 { tmpPro["bidopentime"] = bidopentime } //异常标记 if thisinfo.TopType != "招标" && thisinfo.TopType != "拟建" && thisinfo.TopType != "预告" { tmpPro["exception"] = 1 } //projecthref保存 if jsonData, ok := tmp["jsondata"].(map[string]interface{}); ok { if jsonData != nil && qu.ObjToString(jsonData["projecthref"]) != "" { tmpPro["projecthref"] = jsonData["projecthref"] } } //合同编号 if thisinfo.ContractCode != "" { tmpPro["contractcode"] = thisinfo.ContractCode } bs, bt := p.GetBidTypeAndBidStatus(thisinfo) tmpPro["bidtype"] = bs tmpPro["bidstatus"] = bt pkg := PackageFormat(thisinfo, nil) p1 := p.NewCachePinfo(tmpPro["_id"].(primitive.ObjectID), thisinfo, bs, bt, pkg) now := time.Now().Unix() tmpPro["createtime"] = now tmpPro["sourceinfoid"] = thisinfo.Id tmpPro["sourceinfourl"] = tmp["href"] tmpPro["firsttime"] = tmp["publishtime"] tmpPro["lasttime"] = tmp["publishtime"] tmpPro["pici"] = tmp["comeintime"] tmpPro["ids"] = []string{thisinfo.Id} if thisinfo.TopType == "招标" { if thisinfo.SubType != "变更" && thisinfo.SubType != "其它" { tmpPro["zbtime"] = tmp["publishtime"] p1.Zbtime = qu.Int64All(tmp["publishtime"]) } } else if thisinfo.TopType == "结果" || thisinfo.SubType == "合同" { tmpPro["jgtime"] = tmp["publishtime"] p1.Jgtime = thisinfo.Publishtime } if len(thisinfo.Subscopeclass) > 0 { tmpPro["s_subscopeclass"] = strings.Join(thisinfo.Subscopeclass, ",") } if len(thisinfo.Winners) > 0 { tmpPro["s_winner"] = strings.Join(thisinfo.Winners, ",") p1.Winners = thisinfo.Winners } if thisinfo.HasPackage { tmpPro["multipackage"] = 1 tmpPro["package"] = pkg } else { tmpPro["multipackage"] = 0 } //项目评审专家 if len(thisinfo.ReviewExperts) > 0 { tmpPro["review_experts"] = thisinfo.ReviewExperts p1.ReviewExperts = thisinfo.ReviewExperts } //标的物 if thisinfo.Purchasing != "" { tmpPro["purchasing"] = thisinfo.Purchasing p1.Purchasing = thisinfo.Purchasing } //中标候选人 if len(thisinfo.WinnerOrder) > 0 { var list = []string{} for _, v := range thisinfo.WinnerOrder { if BinarySearch(list, qu.ObjToString(v["entname"])) == -1 { list = append(list, qu.ObjToString(v["entname"])) } } tmpPro["winnerorder"] = list p1.Winnerorder = list } p1.InfoFiled = make(map[string]InfoField) infofield := InfoField{ Budget: thisinfo.Budget, Bidamount: thisinfo.Bidamount, ContractCode: thisinfo.ContractCode, ProjectName: thisinfo.ProjectName, ProjectCode: thisinfo.ProjectCode, Bidstatus: bs, } p1.InfoFiled[thisinfo.Id] = infofield res := StructToMap(infofield) tmpPro["infofield"] = map[string]interface{}{ thisinfo.Id: res, } if tmp["budget"] != nil && tmp["budget"] != "" { tmpPro["budget"] = thisinfo.Budget p1.Budgettag = 0 tmpPro["budgettag"] = 0 } else { p1.Budgettag = 1 tmpPro["budgettag"] = 1 } if tmp["bidamount"] != nil && tmp["bidamount"] != "" { tmpPro["bidamount"] = thisinfo.Bidamount p1.Bidamounttag = 0 tmpPro["bidamounttag"] = 0 } else { p1.Bidamounttag = 1 tmpPro["bidamounttag"] = 1 } if p1.Bidamount > 0 { tmpPro["sortprice"] = p1.Bidamount } else if p1.Budget > 0 { tmpPro["sortprice"] = p1.Budget } push := p.PushListInfo(tmp, thisinfo.Id) push["s_winner"] = strings.Join(thisinfo.Winners, ",") tmpPro["list"] = []map[string]interface{}{ push, } return &p1 } // 合并字段到老项目中 func (p *ProjectTask) updateOldProField(pInfo *ProjectInfo, thisinfo *Info, tmpPro, tmp, m1 map[string]interface{}) { if len(pInfo.Ids) > 30 { //异常标记 tmpPro["listtag"] = 1 } if thisinfo.Publishtime > pInfo.LastTime { pInfo.LastTime = thisinfo.Publishtime tmpPro["lasttime"] = thisinfo.Publishtime } if thisinfo.TopType == "招标" { if thisinfo.SubType != "变更" && thisinfo.SubType != "其它" && pInfo.Zbtime <= 0 { tmpPro["zbtime"] = tmp["publishtime"] } } else if thisinfo.TopType == "结果" { if thisinfo.SubType == "中标" || thisinfo.SubType == "成交" || thisinfo.SubType == "流标" || thisinfo.SubType == "废标" { if pInfo.Jgtime > 0 { jg1 := int64(math.Abs(float64(pInfo.Jgtime - thisinfo.Publishtime))) //公告状态和项目状态同样都是中标或者成交, if (thisinfo.SubType == "中标" || thisinfo.SubType == "成交") && (pInfo.Bidstatus == "中标" || pInfo.Bidstatus == "成交") { if jg1 > p.jgTime { tmpPro["jgtime"] = tmp["publishtime"] pInfo.Jgtime = thisinfo.Publishtime } } else if (thisinfo.SubType == "流标" || thisinfo.SubType == "废标") && (pInfo.Bidstatus == "流标" || pInfo.Bidstatus == "废标") { //公告状态和项目状态同样是流标或者废标 if jg1 > p.jgTime { tmpPro["jgtime"] = tmp["publishtime"] pInfo.Jgtime = thisinfo.Publishtime } } } else { tmpPro["jgtime"] = tmp["publishtime"] pInfo.Jgtime = thisinfo.Publishtime } } } else if thisinfo.SubType == "合同" { if pInfo.Bidstatus == "中标" || pInfo.Bidstatus == "成交" || pInfo.Bidstatus == "" { //中标、成交不更新jgtime } else { tmpPro["jgtime"] = tmp["publishtime"] pInfo.Jgtime = thisinfo.Publishtime } } if thisinfo.Bidopentime > pInfo.Bidopentime { pInfo.Bidopentime = thisinfo.Bidopentime tmpPro["bidopentime"] = pInfo.Bidopentime } // bidtype、bidstatus pInfo.Bidtype, pInfo.Bidstatus = p.GetBidTypeAndBidStatus(thisinfo) tmpPro["bidtype"] = pInfo.Bidtype tmpPro["bidstatus"] = pInfo.Bidstatus //相同城市的公告才会合并到一起(全国列外) if thisinfo.Area != "全国" { pInfo.Area = thisinfo.Area tmpPro["area"] = thisinfo.Area pInfo.City = thisinfo.City tmpPro["city"] = thisinfo.City if thisinfo.District != "" { pInfo.District = thisinfo.District tmpPro["district"] = thisinfo.District } } // 项目名称 if (thisinfo.ProjectName != "" && pInfo.ProjectName == "") || (len([]rune(pInfo.ProjectName)) < 6 && thisinfo.LenPN > 6) { pInfo.ProjectName = thisinfo.ProjectName tmpPro["projectname"] = thisinfo.ProjectName } // 项目编号 if (pInfo.ProjectCode == "" && thisinfo.ProjectCode != "") || (len([]rune(pInfo.ProjectCode)) < 6 && len([]rune(thisinfo.ProjectCode)) > 6) { pInfo.ProjectCode = thisinfo.ProjectCode tmpPro["projectcode"] = thisinfo.ProjectCode } // 采购单位 if (pInfo.Buyer == "" && thisinfo.Buyer != "") || (len([]rune(pInfo.Buyer)) < 5 && len([]rune(thisinfo.Buyer)) > 5) { pInfo.Buyer = thisinfo.Buyer tmpPro["buyer"] = thisinfo.Buyer pInfo.Buyerclass = thisinfo.Buyerclass tmpPro["buyerclass"] = thisinfo.Buyerclass } if pInfo.Buyer == "" { tmpPro["buyerclass"] = "" } // 采购单位联系人 if thisinfo.Buyerperson != "" { pInfo.Buyerperson = thisinfo.Buyerperson tmpPro["buyerperson"] = pInfo.Buyerperson } else { pInfo.Buyerperson = "" tmpPro["buyerperson"] = "" } // 采购单位電話 if thisinfo.Buyertel != "" { pInfo.Buyertel = thisinfo.Buyertel tmpPro["buyertel"] = pInfo.Buyertel } else { pInfo.Buyertel = "" tmpPro["buyertel"] = "" } if thisinfo.ContractCode != "" { tmpPro["contractcode"] = pInfo.ContractCode + "," + thisinfo.ContractCode } // 代理机构 相同的代理机构才会合并到一个项目 2020.11.9 //if (pInfo.Agency == "" && thisinfo.Agency != "") || (len([]rune(pInfo.Agency)) < 5 && len([]rune(thisinfo.Agency)) > 5) { // pInfo.Agency = thisinfo.Agency // set["agency"] = thisinfo.Agency //} if len(thisinfo.Topscopeclass) > 0 { sort.Strings(pInfo.Topscopeclass) for _, k := range thisinfo.Topscopeclass { if BinarySearch(pInfo.Topscopeclass, k) == -1 { pInfo.Topscopeclass = append(pInfo.Topscopeclass, k) sort.Strings(pInfo.Topscopeclass) } } tmpPro["topscopeclass"] = pInfo.Topscopeclass } // 项目评审专家 if len(thisinfo.ReviewExperts) > 0 { tmpPro["review_experts"] = thisinfo.ReviewExperts pInfo.ReviewExperts = thisinfo.ReviewExperts } if thisinfo.Purchasing != "" { if pInfo.Purchasing == "" { pInfo.Purchasing = thisinfo.Purchasing tmpPro["purchasing"] = thisinfo.Purchasing } else { list := strings.Split(pInfo.Purchasing, ",") for _, k := range list { if BinarySearch(strings.Split(thisinfo.Purchasing, ","), k) == -1 { list = append(list, k) sort.Strings(list) } } tmpPro["purchasing"] = strings.Join(list, ",") } } //中标候选人 if len(thisinfo.WinnerOrder) > 0 { var list = []string{} for _, v := range thisinfo.WinnerOrder { if BinarySearch(list, qu.ObjToString(v["entname"])) == -1 { list = append(list, qu.ObjToString(v["entname"])) } } tmpPro["winnerorder"] = list pInfo.Winnerorder = list } if len(thisinfo.Subscopeclass) > 0 { sort.Strings(pInfo.Subscopeclass) for _, k := range thisinfo.Subscopeclass { if BinarySearch(pInfo.Subscopeclass, k) == -1 { pInfo.Subscopeclass = append(pInfo.Subscopeclass, k) sort.Strings(pInfo.Subscopeclass) } } tmpPro["subscopeclass"] = pInfo.Subscopeclass tmpPro["s_subscopeclass"] = strings.Join(pInfo.Subscopeclass, ",") } if len(thisinfo.Winners) > 0 { if len(pInfo.Winners) <= 0 { tmpPro["winner"] = qu.ObjToString(tmp["winner"]) } sort.Strings(pInfo.Winners) for _, k := range thisinfo.Winners { if thisinfo.SubType == "流标" || thisinfo.SubType == "废标" { if BinarySearch(pInfo.Winners, k) != -1 { deleteSlice(pInfo.Winners, k, "") sort.Strings(pInfo.Winners) } } else { if BinarySearch(pInfo.Winners, k) == -1 { pInfo.Winners = append(pInfo.Winners, k) sort.Strings(pInfo.Winners) } } } tmpPro["s_winner"] = strings.Join(pInfo.Winners, ",") } if thisinfo.HasPackage { //多包处理 tmpPro["multipackage"] = 1 pkg := PackageFormat(thisinfo, pInfo) pInfo.Package = pkg tmpPro["package"] = pInfo.Package } //处理多包后,计算预算金额、中标金额 CountAmount(pInfo, thisinfo, tmp) if pInfo.Budget >= 0 && pInfo.Budgettag != 1 { tmpPro["budget"] = pInfo.Budget tmpPro["budgettag"] = 0 } if pInfo.Bidamount >= 0 && pInfo.Bidamounttag != 1 { tmpPro["bidamount"] = pInfo.Bidamount tmpPro["bidamounttag"] = 0 } if pInfo.Bidamount >= pInfo.Budget { tmpPro["sortprice"] = pInfo.Bidamount } else if pInfo.Budget >= pInfo.Bidamount { tmpPro["sortprice"] = pInfo.Budget } infofield := InfoField{ Budget: thisinfo.Budget, Bidamount: thisinfo.Bidamount, ContractCode: thisinfo.ContractCode, ProjectName: thisinfo.ProjectName, ProjectCode: thisinfo.ProjectCode, Bidstatus: pInfo.Bidstatus, } copyMap := Copy(pInfo.InfoFiled).(map[string]InfoField) copyMap[thisinfo.Id] = infofield tmpMap := make(map[string]interface{}) for k, v := range copyMap { tmpMap[k] = StructToMap(v) } tmpMap[thisinfo.Id] = StructToMap(infofield) pInfo.InfoFiled = copyMap tmpPro["infofield"] = tmpMap tmpPro["mpn"] = pInfo.MPN tmpPro["mpc"] = pInfo.MPC tmpPro["updatetime"] = p.pici push := p.PushListInfo(tmp, thisinfo.Id) push["s_winner"] = strings.Join(thisinfo.Winners, ",") push["compareStr"] = m1["compareStr"] push["resVal"] = m1["resVal"] push["pjVal"] = m1["pjVal"] list := tmpPro["list"].([]map[string]interface{}) tmpPro["list"] = append(list, push) tmpPro["ids"] = append(tmpPro["ids"].([]string), thisinfo.Id) } func deleteSlice1(arr []interface{}, v interface{}) []interface{} { for k, v1 := range arr { if reflect.DeepEqual(v1, v) { return append(arr[:k], arr[k+1:]...) } } return arr } // 修改字段值 func UpdateValue(proMap map[string]interface{}, index, position int, modifyMap map[string]interface{}) map[string]interface{} { updataSet := make(map[string]interface{}) infoList := []interface{}(proMap["list"].(primitive.A)) tempMap := infoList[position].(map[string]interface{}) for k := range modifyMap { //项目中lsit大小等于1 或者 修改的招标公告处于项目的list中最后一个 if len(infoList) == 1 || index == 2 { if k == "budget" || k == "bidamount" { if proMap["sortprice"] == proMap[k] { updataSet["sortprice"] = modifyMap[k] } updataSet[k] = modifyMap[k] proMap[k] = modifyMap[k] tempMap[k] = modifyMap[k] }else { updataSet[k] = modifyMap[k] proMap[k] = modifyMap[k] tempMap[k] = modifyMap[k] } } else { tempMap[k] = modifyMap[k] if k == "budget" || k == "bidamount" { if proMap["sortprice"] == proMap[k] { proMap["sortprice"] = modifyMap[k] } updataSet[k] = modifyMap[k] proMap[k] = modifyMap[k] } // 有条件更新项目外围字段值(非空) if proMap[k] == nil || qu.ObjToString(k) == "" { updataSet[k] = modifyMap[k] proMap[k] = modifyMap[k] } } } return updataSet } //备份(快照) func backupPro(tmp map[string]interface{}) { tmp1 := make(map[string]interface{}) for k, v := range tmp{ tmp1[k] = v } if Sysconfig["backupFlag"].(bool) { tmp1["sourceprojectid"] = BsonIdToSId(tmp1["_id"]) delete(tmp1, "_id") MongoTool.Save(BackupColl, tmp1) } } // 删除原有项目数据 func delOldPro(pid string) { t := MongoTool.Delete(ProjectColl, pid) if t >=0 { client := Es.GetEsConn() defer Es.DestoryEsConn(client) Es.DelById(Index, Itype, pid) } } // 修改内存中的数据 func (p *ProjectTask) modifyMem(tmpPro map[string]interface{}) { pid := qu.ObjToString(tmpPro["_id"]) var pro ProjectInfo err := mapstructure.Decode(tmpPro, &pro) if err != nil { qu.Debug(err) } pro.Id = StringTOBsonId(pid) tmpMap := make(map[string]InfoField) infoMap := tmpPro["infofield"].(map[string]interface{}) for _, v := range infoMap { var field InfoField b, _ := json.Marshal(v) _ = json.Unmarshal(b, &field) tmpMap[pid] = field } pro.InfoFiled = tmpMap p.AllIdsMapLock.Lock() if v, ok := p.AllIdsMap[pid]; ok { v.P = &pro } p.AllIdsMapLock.Unlock() p.printMemPro(pid) } // 打印内存中的项目信息 func (p *ProjectTask) printMemPro(pid string) { p.AllIdsMapLock.Lock() if v, ok := p.AllIdsMap[pid]; ok { qu.Debug("mem pro ----------", *v.P) } p.AllIdsMapLock.Unlock() }