123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- package main
- import (
- "github.com/go-xweb/log"
- "go.mongodb.org/mongo-driver/bson/primitive"
- "math"
- qu "qfw/util"
- "reflect"
- "sort"
- "strings"
- )
- func (p *ProjectTask) modifyUpdate(pInfoId string, index int, info *Info, tmp map[string]interface{}, tmpPro map[string]interface{}, modifyMap map[string]interface{}) {
- backupPro(tmpPro)
- infoList := []interface{}(tmpPro["list"].(primitive.A))
- infoMap := infoList[index].(map[string]interface{})
- infoList[index] = updateValue(infoMap, modifyMap)
- set := map[string]interface{}{
- "$set": tmpPro,
- }
- _ = MongoTool.UpdateById(ProjectColl, pInfoId, set)
- }
- func (p *ProjectTask) mergeAndModify(pInfoId string, index int, info *Info, tmp map[string]interface{}, tmpPro map[string]interface{}, modifyMap map[string]interface{}) {
- p.AllIdsMapLock.Lock()
- currentPro := p.AllIdsMap[pInfoId]
- p.AllIdsMapLock.Unlock()
- merge, pId, i, comStr, mergePro := p.updateMerge(index, info, pInfoId, tmp, tmpPro)
- //招标信息在list中第1个
- if index == 0 {
- log.Println("第1条合并", "------1------")
- //快照
- backupPro(tmpPro)
- p.AllIdsMapLock.Lock()
- delete(p.AllIdsMap, pInfoId)
- p.AllIdsMapLock.Unlock()
- count := MongoTool.Delete(ProjectColl, pInfoId)
- log.Println(count)
- for _, infoId := range currentPro.P.Ids{
- if infoId == info.Id {
- continue
- }
- tmp1 := MongoTool.FindById(ExtractColl, infoId)
- info1 := ParseInfo(tmp1)
- p.CommonMerge(tmp1, info1)
- }
- }else {
- log.Println("第n条合并", "------n------")
- //快照 招标信息所在的项目
- backupPro(tmpPro)
- if merge {
- //跟原项目list第0条信息作对比,可以合并
- if pId == pInfoId {
- //合并到当前项目
- mergeProject(p, currentPro.P, info, tmpPro, index)
- p.AllIdsMapLock.Lock()
- p.AllIdsMap[currentPro.P.Id.Hex()].P = currentPro.P
- p.AllIdsMapLock.Unlock()
- infoList := []interface{}(tmpPro["list"].(primitive.A))
- infoMap := infoList[index].(map[string]interface{})
- infoList[index] = updateValue(infoMap, modifyMap)
- set := map[string]interface{}{
- "$set": tmpPro,
- }
- MongoTool.UpdateById(ProjectColl, pInfoId, set)
- }else {
- //合并到的其它项目里边
- //更新其它的项目
- pro := MongoTool.FindById(ProjectColl, mergePro.Id.Hex())
- backupPro(pro, )
- choose, ex := p.CompareStatus(mergePro, info)
- if !choose {
- p.UpdateProject(tmp, info, mergePro, i, comStr, ex)
- }else {
- id, p1 := p.NewProject(tmp, info)
- p.AllIdsMapLock.Lock()
- p.AllIdsMap[id] = &ID{Id: id, P: p1}
- p.AllIdsMapLock.Unlock()
- }
- //内部合并
- p.innerMerge(currentPro.P, info, tmp, tmpPro)
- }
- }else {
- //合并到新建的项目里边,原有项目内部合并
- p.innerMerge(currentPro.P, info, tmp, tmpPro)
- }
- }
- }
- func (p *ProjectTask) updateMerge(index int, info *Info, pInfoId string, tmp map[string]interface{}, tmpPro map[string]interface{}) (bool, string, int, string, *ProjectInfo) {
- 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 := ""
- //获取完id,进行计算
- //定义两组
- comRes1 := []*ProjectInfo{} //优先级最高的对比结果数组
- comRes2 := []*ProjectInfo{} //优化级其次
- comRes3 := []*ProjectInfo{}
- for _, v := range IDArr {
- if index == 0 && pInfoId == v.P.Id.Hex() {
- //招标条目信息在原项目中是第0条时,忽略
- continue
- }
- 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)
- }
- }
- }
- }
- //--------------------------------对比完成-----------------------
- k := -1
- comStr := ""
- mergePro := &ProjectInfo{}
- 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 _, res := range resN{
- choose, e := p.CompareStatus(resN[0], info)
- if !choose {
- ex = e
- resArr = append(resArr, res)
- }
- }
- if len(resArr) > 0 {
- bFindProject = true
- findPid = resArr[0].Id.Hex()
- 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
- }
- }
- }
- }
- if index != 0 {
- //招标条目信息在原项目中是第非0条时,返回对比结果
- k = kv+1
- comStr = resArr[0].comStr
- mergePro = resArr[0]
- bFindProject = false
- findPid = ""
- }else {
- mergePro = resArr[0]
- //如果有合并,合并之前备份(快照)
- backupPro(tmpPro)
- p.UpdateProject(tmp, info, resArr[0], kv+1, resArr[0].comStr, ex)
- }
- }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 bFindProject, findPid, k, comStr, mergePro
- }
- //内部合并
- func (p *ProjectTask) innerMerge(pInfo *ProjectInfo, info *Info, tmp map[string]interface{}, tmpPro map[string]interface{}) {
- infoList := []interface{}(tmpPro["list"].(primitive.A))
- for index, info1 := range infoList{
- info2 := info1.(map[string]interface{})
- if info2["infoid"] == info.Id {
- deleteSlice1(infoList, info1)
- continue
- }
- mergeProject(p, pInfo, info, tmpPro, index)
- }
- set := map[string]interface{}{
- "$set": tmpPro,
- }
- MongoTool.UpdateById(ProjectColl, pInfo.Id.Hex(), set)
- }
- //合并字段到project
- func mergeProject(p *ProjectTask, pInfo *ProjectInfo, thisinfo *Info, set map[string]interface{}, index int) map[string]interface{} {
- //1--firsttime
- if thisinfo.Publishtime < pInfo.FirstTime && thisinfo.Publishtime > 0 {
- pInfo.FirstTime = thisinfo.Publishtime
- set["firsttime"] = thisinfo.Publishtime
- if thisinfo.TopType == "招标" {
- set["zbtime"] = thisinfo.Publishtime
- }
- }
- //2--lasttime
- pInfo.LastTime = thisinfo.Publishtime
- set["lasttime"] = thisinfo.Publishtime
- if thisinfo.TopType == "招标" {
- set["zbtime"] = thisinfo.Publishtime
- } else if thisinfo.TopType == "结果" || thisinfo.SubType == "合同" {
- set["jgtime"] = thisinfo.Publishtime
- }
- //废标、流标 处理时间
- if thisinfo.SubType == "流标" || thisinfo.SubType == "废标" {
- pInfo.FirstTime = thisinfo.Publishtime
- pInfo.Bidopentime = int64(0)
- pInfo.LastTime = thisinfo.Publishtime
- set["firsttime"] = thisinfo.Publishtime
- set["zbtime"] = int64(0)
- set["publishtime"] = thisinfo.Publishtime
- set["bidopentime"] = int64(0)
- }
- bt := thisinfo.TopType
- bs := thisinfo.SubType
- p.mapBidLock.Lock()
- if bt == "招标" {
- //招标状态,更新projectscope
- if thisinfo.ProjectScope != "" {
- set["projectscope"] = thisinfo.ProjectScope
- }
- set["bidtype"] = bidtype[bs]
- }else {
- set["bidtype"] = bt
- if bidstatus[bs] != "" {
- set["bidstatus"] = thisinfo.SubType
- } else if thisinfo.Infoformat == 2 {
- set["bidstatus"] = "拟建"
- } else {
- set["bidstatus"] = "其它"
- }
- }
- p.mapBidLock.Unlock()
- //3\4\5--省、市、县
- if thisinfo.Area != "全国" {
- //xt := true
- if pInfo.Area == "全国" {
- pInfo.Area = thisinfo.Area
- set["area"] = thisinfo.Area
- } else if pInfo.Area != thisinfo.Area {
- //xt = false
- }
- if pInfo.City == "" && thisinfo.City != "" {
- pInfo.City = thisinfo.City
- set["city"] = thisinfo.City
- } else if pInfo.City != thisinfo.City {
- //xt = false
- }
- if thisinfo.District != "" && pInfo.District == "" {
- pInfo.District = thisinfo.District
- set["district"] = thisinfo.District
- }
- }
- //6--项目名称
- if (thisinfo.ProjectName != "" && pInfo.ProjectName == "") || (len([]rune(pInfo.ProjectName)) < 6 && thisinfo.LenPN > 6) {
- pInfo.ProjectName = thisinfo.ProjectName
- set["projectname"] = thisinfo.ProjectName
- }
- //7--项目编号
- if (pInfo.ProjectCode == "" && thisinfo.ProjectCode != "") || (len([]rune(pInfo.ProjectCode)) < 6 && len([]rune(thisinfo.ProjectCode)) > 6) {
- pInfo.ProjectCode = thisinfo.ProjectCode
- set["projectcode"] = thisinfo.ProjectCode
- }
- //7--采购单位
- 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"] = ""
- }
- //8--代理机构
- if (pInfo.Agency == "" && thisinfo.Agency != "") || (len([]rune(pInfo.Agency)) < 5 && len([]rune(thisinfo.Agency)) > 5) {
- pInfo.Agency = thisinfo.Agency
- set["agency"] = thisinfo.Agency
- }
- //9--采购单位联系人
- if thisinfo.Buyerperson != "" && strings.Index(pInfo.Buyerperson, thisinfo.Buyerperson) < 0 {
- pInfo.Buyerperson = thisinfo.Buyerperson
- set["buyerperson"] = pInfo.Buyerperson
- }
- //10--采购单位電話
- if thisinfo.Buyertel != "" && strings.Index(pInfo.Buyertel, thisinfo.Buyertel) < 0 {
- pInfo.Buyertel = thisinfo.Buyertel
- set["buyertel"] = pInfo.Buyertel
- }
- if thisinfo.Bidopentime > pInfo.Bidopentime {
- pInfo.Bidopentime = thisinfo.Bidopentime
- set["bidopentime"] = pInfo.Bidopentime
- }
- //废标、流标 处理时间
- if thisinfo.SubType == "流标" || thisinfo.SubType == "废标" {
- pInfo.FirstTime = thisinfo.Publishtime
- pInfo.Bidopentime = int64(0)
- pInfo.LastTime = thisinfo.Publishtime
- set["firsttime"] = thisinfo.Publishtime
- set["zbtime"] = int64(0)
- set["publishtime"] = thisinfo.Publishtime
- set["bidopentime"] = int64(0)
- }
- 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)
- }
- }
- set["topscopeclass"] = pInfo.Topscopeclass
- }
- 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)
- }
- }
- set["subscopeclass"] = pInfo.Subscopeclass
- set["s_subscopeclass"] = strings.Join(pInfo.Subscopeclass, ",")
- }
- //winner
- if len(thisinfo.Winners) > 0 {
- sort.Strings(pInfo.Winners)
- for _, k := range thisinfo.Winners {
- if BinarySearch(pInfo.Winners, k) == -1 {
- pInfo.Winners = append(pInfo.Winners, k)
- sort.Strings(pInfo.Winners)
- }
- }
- //set["winners"] = pInfo.Winners
- set["s_winner"] = strings.Join(pInfo.Winners, ",")
- }
- if thisinfo.HasPackage {
- pkg := PackageFormat(thisinfo, pInfo)
- set["multipackage"] = 1
- pInfo.Package = pkg
- }else {
- set["multipackage"] = 0
- }
- //处理多包后,计算预算金额、中标金额
- CountAmount(pInfo, thisinfo)
- set["budget"] = pInfo.Budget
- set["bidamount"] = pInfo.Bidamount
- set["mpn"] = pInfo.MPN
- set["mpc"] = pInfo.MPC
- set["pici"] = p.pici
- return set
- }
- 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(info map[string]interface{}, tmp map[string]interface{}) map[string]interface{} {
- for k := range info{
- for k1 := range tmp {
- if k == k1 && info[k] != tmp[k1] {
- info[k] = tmp[k]
- break
- }
- }
- }
- return info
- }
- //备份(快照)
- 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"] = tmp1["_id"]
- delete(tmp1, "_id")
- MongoTool.Save(BackupColl, tmp1)
- }
- }
|