update.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. package main
  2. import (
  3. "github.com/go-xweb/log"
  4. "go.mongodb.org/mongo-driver/bson/primitive"
  5. "math"
  6. qu "qfw/util"
  7. "reflect"
  8. "sort"
  9. "strings"
  10. )
  11. func (p *ProjectTask) modifyUpdate(pInfoId string, index int, info *Info, tmp map[string]interface{}, tmpPro map[string]interface{}, modifyMap map[string]interface{}) {
  12. backupPro(tmpPro)
  13. infoList := []interface{}(tmpPro["list"].(primitive.A))
  14. infoMap := infoList[index].(map[string]interface{})
  15. infoList[index] = updateValue(infoMap, modifyMap)
  16. set := map[string]interface{}{
  17. "$set": tmpPro,
  18. }
  19. err := MongoTool.UpdateById(ProjectColl, pInfoId, set)
  20. log.Println(err)
  21. }
  22. func (p *ProjectTask) mergeAndModify(pInfoId string, index int, info *Info, tmp map[string]interface{}, tmpPro map[string]interface{}, modifyMap map[string]interface{}) {
  23. p.AllIdsMapLock.Lock()
  24. currentPro := p.AllIdsMap[pInfoId]
  25. p.AllIdsMapLock.Unlock()
  26. merge, pId, i, comStr, mergePro := p.updateMerge(index, info, pInfoId, tmp, tmpPro)
  27. //招标信息在list中第1个
  28. if index == 0 {
  29. log.Println("第1条合并", "------1------")
  30. //快照
  31. backupPro(tmpPro)
  32. p.AllIdsMapLock.Lock()
  33. delete(p.AllIdsMap, pInfoId)
  34. p.AllIdsMapLock.Unlock()
  35. count := MongoTool.Delete(ProjectColl, pInfoId)
  36. log.Println(count)
  37. for _, infoId := range currentPro.P.Ids{
  38. if infoId == info.Id {
  39. continue
  40. }
  41. tmp1 := MongoTool.FindById(ExtractColl, infoId)
  42. info1 := ParseInfo(tmp1)
  43. p.CommonMerge(tmp1, info1)
  44. }
  45. }else {
  46. log.Println("第n条合并", "------n------")
  47. //快照 招标信息所在的项目
  48. backupPro(tmpPro)
  49. if merge {
  50. //跟原项目list第0条信息作对比,可以合并
  51. if pId == pInfoId {
  52. //合并到当前项目
  53. mergeProject(p, currentPro.P, info, tmpPro, index)
  54. p.AllIdsMapLock.Lock()
  55. p.AllIdsMap[currentPro.P.Id.Hex()].P = currentPro.P
  56. p.AllIdsMapLock.Unlock()
  57. infoList := []interface{}(tmpPro["list"].(primitive.A))
  58. infoMap := infoList[index].(map[string]interface{})
  59. infoList[index] = updateValue(infoMap, modifyMap)
  60. set := map[string]interface{}{
  61. "$set": tmpPro,
  62. }
  63. MongoTool.UpdateById(ProjectColl, pInfoId, set)
  64. }else {
  65. //合并到的其它项目里边
  66. //更新其它的项目
  67. pro := MongoTool.FindById(ProjectColl, mergePro.Id.Hex())
  68. backupPro(pro, )
  69. choose, ex := CompareStatus(mergePro, info)
  70. if !choose {
  71. p.UpdateProject(tmp, info, mergePro, i, comStr, ex)
  72. }else {
  73. id, p1 := p.NewProject(tmp, info)
  74. p.AllIdsMapLock.Lock()
  75. p.AllIdsMap[id] = &ID{Id: id, P: p1}
  76. p.AllIdsMapLock.Unlock()
  77. }
  78. //内部合并
  79. p.innerMerge(currentPro.P, info, tmp, tmpPro)
  80. }
  81. }else {
  82. //合并到新建的项目里边,原有项目内部合并
  83. p.innerMerge(currentPro.P, info, tmp, tmpPro)
  84. }
  85. }
  86. }
  87. func (p *ProjectTask) updateMerge(index int, info *Info, pInfoId string, tmp map[string]interface{}, tmpPro map[string]interface{}) (bool, string, int, string, *ProjectInfo) {
  88. bpn, bpc, bptc, bpb, pids, _, IDArr := p.getCompareIds(info.ProjectName, info.ProjectCode, info.PTC, info.Buyer)
  89. defer p.wg.Done()
  90. for _, m := range pids {
  91. defer m.Lock.Unlock()
  92. }
  93. for _, id := range IDArr {
  94. defer id.Lock.Unlock()
  95. }
  96. bFindProject := false
  97. findPid := ""
  98. //获取完id,进行计算
  99. //定义两组
  100. comRes1 := []*ProjectInfo{} //优先级最高的对比结果数组
  101. comRes2 := []*ProjectInfo{} //优化级其次
  102. comRes3 := []*ProjectInfo{}
  103. for _, v := range IDArr {
  104. if index == 0 && pInfoId == v.P.Id.Hex() {
  105. //招标条目信息在原项目中是第0条时,忽略
  106. continue
  107. }
  108. comStr := ""
  109. compareProject := v.P
  110. compareProject.score = 0
  111. diffTime := int64(math.Abs(float64(info.Publishtime - compareProject.LastTime)))
  112. if diffTime <= p.validTime {
  113. //代理机构完全不相同,直接新建项目
  114. if CheckContain(compareProject.Agency, info.Agency) == 3 {
  115. continue
  116. }
  117. //地区(省、市、区)不同,直接新建项目
  118. if ComparePlace(compareProject, info) {
  119. continue
  120. }
  121. info.PNBH = 0
  122. info.PCBH = 0
  123. info.PTCBH = 0
  124. compareStr, score := comparePNC(info, compareProject)
  125. resVal, pjVal := Select(compareStr, info, compareProject)
  126. if resVal > 0 {
  127. compareBuyer, compareCity, compareTime, compareAgency, compareBudget, compareBidmount, score2 := p.compareBCTABB(info, compareProject, diffTime, score)
  128. //项目名称、项目编号、标题项目编号、采购单位、省、市、发布时间、代理机构
  129. comStr = compareStr + compareBuyer + compareCity + compareTime + compareAgency + compareBudget + compareBidmount
  130. compareProject.comStr = comStr
  131. compareProject.pjVal = pjVal
  132. compareProject.resVal = resVal
  133. eqV := compareResult(resVal, pjVal, score2, comStr, compareBuyer, compareCity, compareTime, compareAgency, compareBudget, compareBidmount)
  134. if eqV == 1 {
  135. comRes1 = append(comRes1, compareProject)
  136. } else if eqV == 2 {
  137. comRes2 = append(comRes2, compareProject)
  138. } else if eqV == 3 {
  139. comRes3 = append(comRes3, compareProject)
  140. }
  141. }
  142. }
  143. }
  144. //--------------------------------对比完成-----------------------
  145. k := -1
  146. comStr := ""
  147. mergePro := &ProjectInfo{}
  148. for kv, resN := range [][]*ProjectInfo{comRes1, comRes2, comRes3} {
  149. if len(resN) > 0 {
  150. if len(resN) > 1 {
  151. sort.Slice(resN, func(i, j int) bool {
  152. return resN[i].score > resN[j].score
  153. })
  154. }
  155. ex := 0
  156. resArr := []*ProjectInfo{}
  157. for _, res := range resN{
  158. choose, e := CompareStatus(resN[0], info)
  159. if !choose {
  160. ex = e
  161. resArr = append(resArr, res)
  162. }
  163. }
  164. if len(resArr) > 0 {
  165. bFindProject = true
  166. findPid = resArr[0].Id.Hex()
  167. for k2, bv := range []int{bpn, bpc, bptc, bpb} {
  168. if bv > -1 {
  169. pids[bv].Arr = append(pids[bv].Arr, findPid)
  170. if k2 == 0 {
  171. if resArr[0].ProjectName == "" {
  172. resArr[0].ProjectName = info.ProjectName
  173. } else {
  174. if resArr[0].MPN == nil {
  175. resArr[0].MPN = []string{info.ProjectName}
  176. } else {
  177. resArr[0].MPN = append(resArr[0].MPN, info.ProjectName)
  178. }
  179. }
  180. } else if k2 < 3 {
  181. if resArr[0].ProjectCode == "" {
  182. resArr[0].ProjectCode = qu.If(k2 == 1, info.ProjectCode, info.PTC).(string)
  183. } else {
  184. if resArr[0].MPC == nil {
  185. resArr[0].MPC = []string{qu.If(k2 == 1, info.ProjectCode, info.PTC).(string)}
  186. } else {
  187. resArr[0].MPC = append(resArr[0].MPC, qu.If(k2 == 1, info.ProjectCode, info.PTC).(string))
  188. }
  189. }
  190. } else {
  191. if resArr[0].Buyer == "" {
  192. resArr[0].Buyer = info.Buyer
  193. }
  194. }
  195. }
  196. }
  197. if index != 0 {
  198. //招标条目信息在原项目中是第非0条时,返回对比结果
  199. k = kv+1
  200. comStr = resArr[0].comStr
  201. mergePro = resArr[0]
  202. bFindProject = false
  203. findPid = ""
  204. }else {
  205. mergePro = resArr[0]
  206. //如果有合并,合并之前备份(快照)
  207. backupPro(tmpPro)
  208. p.UpdateProject(tmp, info, resArr[0], kv+1, resArr[0].comStr, ex)
  209. }
  210. }else {
  211. bFindProject = false
  212. findPid = ""
  213. }
  214. break
  215. }
  216. }
  217. if !bFindProject {
  218. id, p1 := p.NewProject(tmp, info)
  219. p.AllIdsMapLock.Lock()
  220. p.AllIdsMap[id] = &ID{Id: id, P: p1}
  221. p.AllIdsMapLock.Unlock()
  222. for _, m := range pids {
  223. m.Arr = append(m.Arr, id)
  224. }
  225. }
  226. return bFindProject, findPid, k, comStr, mergePro
  227. }
  228. //内部合并
  229. func (p *ProjectTask) innerMerge(pInfo *ProjectInfo, info *Info, tmp map[string]interface{}, tmpPro map[string]interface{}) {
  230. infoList := []interface{}(tmpPro["list"].(primitive.A))
  231. for index, info1 := range infoList{
  232. info2 := info1.(map[string]interface{})
  233. if info2["infoid"] == info.Id {
  234. deleteSlice1(infoList, info1)
  235. continue
  236. }
  237. mergeProject(p, pInfo, info, tmpPro, index)
  238. }
  239. p.AllIdsMapLock.Lock()
  240. p.AllIdsMap[pInfo.Id.Hex()].P = pInfo
  241. p.AllIdsMapLock.Unlock()
  242. set := map[string]interface{}{
  243. "$set": tmpPro,
  244. }
  245. MongoTool.UpdateById(ProjectColl, pInfo.Id.Hex(), set)
  246. }
  247. //合并字段到project
  248. func mergeProject(p *ProjectTask, pInfo *ProjectInfo, thisinfo *Info, set map[string]interface{}, index int) map[string]interface{} {
  249. //1--firsttime
  250. if thisinfo.Publishtime < pInfo.FirstTime && thisinfo.Publishtime > 0 {
  251. pInfo.FirstTime = thisinfo.Publishtime
  252. set["firsttime"] = thisinfo.Publishtime
  253. if thisinfo.TopType == "招标" {
  254. set["zbtime"] = thisinfo.Publishtime
  255. }
  256. }
  257. //2--lasttime
  258. if thisinfo.Publishtime > pInfo.LastTime {
  259. pInfo.LastTime = thisinfo.Publishtime
  260. set["lasttime"] = thisinfo.Publishtime
  261. bt := bidtype[thisinfo.SubType]
  262. if bt != "" {
  263. set["bidtype"] = bt
  264. }
  265. if thisinfo.SubType != "" {
  266. set["bidstatus"] = thisinfo.SubType
  267. if thisinfo.SubType != "预告" {
  268. set["jgtime"] = thisinfo.Publishtime
  269. }
  270. }else if thisinfo.Infoformat == 2 {
  271. set["bidstatus"] = "拟建"
  272. }else if thisinfo.SubType == "招标" {
  273. set["bidstatus"] = thisinfo.TopType
  274. }else {
  275. set["bidstatus"] = thisinfo.SubType
  276. }
  277. }
  278. //3\4\5--省、市、县
  279. if thisinfo.Area != "全国" {
  280. //xt := true
  281. if pInfo.Area == "全国" {
  282. pInfo.Area = thisinfo.Area
  283. set["area"] = thisinfo.Area
  284. } else if pInfo.Area != thisinfo.Area {
  285. //xt = false
  286. }
  287. if pInfo.City == "" && thisinfo.City != "" {
  288. pInfo.City = thisinfo.City
  289. set["city"] = thisinfo.City
  290. } else if pInfo.City != thisinfo.City {
  291. //xt = false
  292. }
  293. if thisinfo.District != "" && pInfo.District == "" {
  294. pInfo.District = thisinfo.District
  295. set["district"] = thisinfo.District
  296. }
  297. }
  298. //6--项目名称
  299. if (thisinfo.ProjectName != "" && pInfo.ProjectName == "") || (len([]rune(pInfo.ProjectName)) < 6 && thisinfo.LenPN > 6) {
  300. pInfo.ProjectName = thisinfo.ProjectName
  301. set["projectname"] = thisinfo.ProjectName
  302. }
  303. //7--项目编号
  304. if (pInfo.ProjectCode == "" && thisinfo.ProjectCode != "") || (len([]rune(pInfo.ProjectCode)) < 6 && len([]rune(thisinfo.ProjectCode)) > 6) {
  305. pInfo.ProjectCode = thisinfo.ProjectCode
  306. set["projectcode"] = thisinfo.ProjectCode
  307. }
  308. //7--采购单位
  309. if (pInfo.Buyer == "" && thisinfo.Buyer != "") || (len([]rune(pInfo.Buyer)) < 5 && len([]rune(thisinfo.Buyer)) > 5) {
  310. pInfo.Buyer = thisinfo.Buyer
  311. set["buyer"] = thisinfo.Buyer
  312. pInfo.Buyerclass = thisinfo.Buyerclass
  313. set["buyerclass"] = thisinfo.Buyerclass
  314. }
  315. if pInfo.Buyer == "" {
  316. set["buyerclass"] = ""
  317. }
  318. //8--代理机构
  319. if (pInfo.Agency == "" && thisinfo.Agency != "") || (len([]rune(pInfo.Agency)) < 5 && len([]rune(thisinfo.Agency)) > 5) {
  320. pInfo.Agency = thisinfo.Agency
  321. set["agency"] = thisinfo.Agency
  322. }
  323. //9--采购单位联系人
  324. if thisinfo.Buyerperson != "" && strings.Index(pInfo.Buyerperson, thisinfo.Buyerperson) < 0 {
  325. pInfo.Buyerperson = thisinfo.Buyerperson
  326. set["buyerperson"] = pInfo.Buyerperson
  327. }
  328. //10--采购单位電話
  329. if thisinfo.Buyertel != "" && strings.Index(pInfo.Buyertel, thisinfo.Buyertel) < 0 {
  330. pInfo.Buyertel = thisinfo.Buyertel
  331. set["buyertel"] = pInfo.Buyertel
  332. }
  333. if thisinfo.Bidopentime > pInfo.Bidopentime {
  334. pInfo.Bidopentime = thisinfo.Bidopentime
  335. set["bidopentime"] = pInfo.Bidopentime
  336. }
  337. if thisinfo.Bidamount > 0 && pInfo.Bidamount < 1 {
  338. pInfo.Bidamount = thisinfo.Bidamount
  339. set["bidamount"] = pInfo.Bidamount
  340. }
  341. if thisinfo.Budget > 0 && pInfo.Budget < 1 { //多包的会有问题,没有进行合计。
  342. pInfo.Budget = thisinfo.Budget
  343. set["budget"] = pInfo.Budget
  344. }
  345. if len(thisinfo.Topscopeclass) > 0 {
  346. sort.Strings(pInfo.Topscopeclass)
  347. for _, k := range thisinfo.Topscopeclass {
  348. if BinarySearch(pInfo.Topscopeclass, k) == -1 {
  349. pInfo.Topscopeclass = append(pInfo.Topscopeclass, k)
  350. sort.Strings(pInfo.Topscopeclass)
  351. }
  352. }
  353. set["topscopeclass"] = pInfo.Topscopeclass
  354. }
  355. if len(thisinfo.Subscopeclass) > 0 {
  356. sort.Strings(pInfo.Subscopeclass)
  357. for _, k := range thisinfo.Subscopeclass {
  358. if BinarySearch(pInfo.Subscopeclass, k) == -1 {
  359. pInfo.Subscopeclass = append(pInfo.Subscopeclass, k)
  360. sort.Strings(pInfo.Subscopeclass)
  361. }
  362. }
  363. set["subscopeclass"] = pInfo.Subscopeclass
  364. set["s_subscopeclass"] = strings.Join(pInfo.Subscopeclass, ",")
  365. }
  366. //winner
  367. if len(thisinfo.Winners) > 0 {
  368. sort.Strings(pInfo.Winners)
  369. for _, k := range thisinfo.Winners {
  370. if BinarySearch(pInfo.Winners, k) == -1 {
  371. pInfo.Winners = append(pInfo.Winners, k)
  372. sort.Strings(pInfo.Winners)
  373. }
  374. }
  375. //set["winners"] = pInfo.Winners
  376. set["s_winner"] = strings.Join(pInfo.Winners, ",")
  377. }
  378. if thisinfo.HasPackage {
  379. pkg, _, _ := PackageFormat(thisinfo, pInfo)
  380. pInfo.Package = pkg
  381. }
  382. set["mpn"] = pInfo.MPN
  383. set["mpc"] = pInfo.MPC
  384. set["pici"] = p.pici
  385. if thisinfo.HasPackage {
  386. set["multipackage"] = 1
  387. } else {
  388. set["multipackage"] = 0
  389. }
  390. return set
  391. }
  392. func deleteSlice1(arr []interface{}, v interface{}) []interface{} {
  393. for k, v1 := range arr {
  394. if reflect.DeepEqual(v1, v) {
  395. return append(arr[:k], arr[k+1:]...)
  396. }
  397. }
  398. return arr
  399. }
  400. func updateValue(info map[string]interface{}, tmp map[string]interface{}) map[string]interface{} {
  401. for k := range info{
  402. for k1 := range tmp {
  403. if k == k1 && info[k] != tmp[k1] {
  404. info[k] = tmp[k]
  405. break
  406. }
  407. }
  408. }
  409. return info
  410. }
  411. //备份(快照)
  412. func backupPro(tmp map[string]interface{}) {
  413. tmp1 := make(map[string]interface{})
  414. for k, v := range tmp{
  415. tmp1[k] = v
  416. }
  417. if Sysconfig["backupFlag"].(bool) {
  418. tmp1["sourceprojectid"] = tmp1["_id"]
  419. delete(tmp1, "_id")
  420. MongoTool.Save(BackupColl, tmp1)
  421. }
  422. }