projectmegerinsert.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. // projectmegerinsert
  2. package main
  3. import (
  4. "encoding/json"
  5. "flag"
  6. "fmt"
  7. du "jy/util"
  8. "log"
  9. qu "qfw/util"
  10. "sort"
  11. "strings"
  12. "sync"
  13. "time"
  14. "gopkg.in/mgo.v2/bson"
  15. )
  16. const (
  17. Select3To2 = iota //三选二合并
  18. Select3To1 //三选一合并
  19. AloneProject //孤立核查项目
  20. InvalidInfo //无效信息
  21. )
  22. var (
  23. OmitNumMax, DeviationDay, HourInterval int64 //提取最大遗漏数据量,项目查询时间修正区间,轮循间隔
  24. InfoRScore = map[string][]*RScoreInfo{}
  25. PnAll, PcAll, PbAll = map[string][]string{}, map[string][]string{}, map[string][]string{}
  26. )
  27. type RScoreInfo struct { //对比结果集
  28. Id string //信息id
  29. Pid string //项目id
  30. Pkey string
  31. Score int
  32. ProjectNameType string
  33. ProjectCodeType string
  34. BuyerType string
  35. AreaType string
  36. AgencyType string
  37. Cresult string
  38. Info *Info
  39. Pinfo *ProjectInfo
  40. }
  41. type MegerInfo struct { //待合并分段数据
  42. StartPublishtime int64
  43. EndPublishtime int64
  44. Num int
  45. Minfo []*Info
  46. Lock *sync.Mutex
  47. }
  48. var StartId string
  49. func main_inc() {
  50. flag.StringVar(&StartId, "StartId", "", "开始_id")
  51. flag.Parse()
  52. //StartId = "56388138af53745d9a000001"
  53. log.Println("StartId", StartId)
  54. if StartId == "" {
  55. return
  56. }
  57. startInsertMeger(StartId)
  58. }
  59. //开始插入合并
  60. func startInsertMeger(startId string) {
  61. datas := getOmitData(startId)
  62. for _, minfo := range datas {
  63. if int64(minfo.Num) < OmitNumMax {
  64. log.Println("分段信息量太小,不执行", minfo.Num)
  65. continue
  66. }
  67. getPncbKey(minfo)
  68. compareMeger(minfo)
  69. //清空相关信息
  70. minfo = nil
  71. InfoRScore = map[string][]*RScoreInfo{}
  72. }
  73. time.AfterFunc(time.Duration(HourInterval)*time.Hour, func() {
  74. startInsertMeger(startId)
  75. })
  76. }
  77. //获取遗漏数据(分段)
  78. func getOmitData(startId string) (list []*MegerInfo) {
  79. log.Println("加载分段信息")
  80. q := map[string]interface{}{
  81. "_id": map[string]interface{}{
  82. "$gt": bson.ObjectIdHex(startId),
  83. },
  84. }
  85. log.Println(MQFW.DbName, extractColl, q)
  86. sess := MQFW.GetMgoConn()
  87. defer MQFW.DestoryMongoConn(sess)
  88. //数据正序处理
  89. it := sess.DB(MQFW.DbName).C(extractColl).Find(q).Sort("publishtime").Iter()
  90. minfo := &MegerInfo{Lock: &sync.Mutex{}, Minfo: []*Info{}}
  91. var lastId string
  92. for tmp := make(map[string]interface{}); it.Next(tmp); {
  93. if qu.IntAll(tmp["repeat"]) == 1 {
  94. continue
  95. }
  96. if tmp["meger_sflag"] != nil {
  97. continue
  98. }
  99. b, mv := isMegerProjectAndProcess(tmp)
  100. if !b { //是否参与合并
  101. if mv == AloneProject {
  102. //生成孤立项目
  103. thisinfo := PreThisInfo(tmp)
  104. newProjectInc(tmp, map[string]interface{}{"meger_sflag": "alone"}, time.Now().Unix(), thisinfo)
  105. }
  106. if mv == InvalidInfo {
  107. //无效信息,打标记
  108. extInfoTag("invalid", qu.BsonIdToSId(tmp["_id"]))
  109. }
  110. continue
  111. }
  112. this := PreThisInfo(tmp)
  113. if this == nil {
  114. continue
  115. }
  116. this.MererInc = mv
  117. this.Data = tmp
  118. tmp = make(map[string]interface{})
  119. if minfo.StartPublishtime == 0 {
  120. minfo.StartPublishtime = this.Publishtime
  121. } else {
  122. minfo.EndPublishtime = this.Publishtime
  123. }
  124. //分段
  125. if (minfo.EndPublishtime-minfo.StartPublishtime)/int64(86400) > DeviationDay*int64(2) || OmitNumMax <= int64(minfo.Num) {
  126. log.Println(len(list), "段信息加载完成,信息量", minfo.Num)
  127. list = append(list, minfo)
  128. minfo = &MegerInfo{}
  129. break
  130. }
  131. lastId = this.Id
  132. minfo.Minfo = append(minfo.Minfo, this)
  133. minfo.Num += 1
  134. }
  135. if minfo.Num > 0 {
  136. list = append(list, minfo)
  137. }
  138. log.Println("getOmitData lastId", lastId)
  139. return
  140. }
  141. //加载分段pncb key
  142. func getPncbKey(minfo *MegerInfo) {
  143. log.Println("pncb key 开始加载")
  144. //计算时间区间
  145. var startTime, endTime int64
  146. if minfo.EndPublishtime+DeviationDay*86400 <= time.Now().Unix() {
  147. startTime = minfo.EndPublishtime - DeviationDay*86400
  148. endTime = minfo.EndPublishtime + DeviationDay*86400
  149. } else {
  150. startTime = minfo.EndPublishtime - DeviationDay*86400 - (minfo.EndPublishtime + DeviationDay*86400 - time.Now().Unix())
  151. endTime = time.Now().Unix()
  152. }
  153. q := map[string]interface{}{
  154. "lastpublishtime": map[string]interface{}{ //lastpublishtime
  155. "$gte": startTime,
  156. "$lte": endTime,
  157. },
  158. }
  159. log.Println("getPncbKey", q, startTime, endTime)
  160. //pn,pc,pb加载内存中
  161. sess := MQFW.GetMgoConn()
  162. defer MQFW.DestoryMongoConn(sess)
  163. it := sess.DB(MQFW.DbName).C(projectColl).Find(q).Sort("lastpublishtime").Iter()
  164. //it := sess.DB(MQFW.DbName).C(projectColl).Find(map[string]interface{}{}).Sort("pici").Iter()
  165. for tmp := make(map[string]interface{}); it.Next(tmp); {
  166. if qu.ObjToString(tmp["meger_sflag"]) == "normal" {
  167. pn := "pn_" + qu.ObjToString(tmp["projectname"])
  168. pc := "pc_" + qu.ObjToString(tmp["projectcode"])
  169. pb := "pb_" + qu.ObjToString(tmp["buyer"])
  170. pid := qu.BsonIdToSId(tmp["_id"])
  171. if len(pn) > 3 {
  172. PnAll[pn] = append(PnAll[pn], pid)
  173. }
  174. if len(pc) > 3 {
  175. PcAll[pc] = append(PnAll[pc], pid)
  176. }
  177. if len(pb) > 3 {
  178. PbAll[pb] = append(PnAll[pb], pid)
  179. }
  180. }
  181. }
  182. log.Println("pncb key 加载完成", "pn:", len(PnAll), "pb:", len(PbAll), "pc:", len(PcAll))
  183. }
  184. //对比打分
  185. func compareMeger(minfo *MegerInfo) {
  186. for _, info := range minfo.Minfo {
  187. pids := PnAll["pn_"+info.ProjectName]
  188. compareScoreMeger("pn", pids, info)
  189. pids = PcAll["pc_"+info.ProjectCode]
  190. compareScoreMeger("pc", pids, info)
  191. pids = PbAll["pb_"+info.Buyer]
  192. compareScoreMeger("pb", pids, info)
  193. infors, _ := InfoRScore[info.Id]
  194. sort.Slice(infors, func(i, j int) bool {
  195. return infors[i].Score > infors[j].Score
  196. })
  197. if len(infors) > 0 { //合并项目
  198. info := infors[0]
  199. info.Info.Data["cresult"] = info.Cresult
  200. info.Info.Data["score"] = info.Score
  201. id := updateinfoInc(info.Info, info.Info.Data, info.Pinfo)
  202. log.Println("合并项目", info.Info.ProjectName, info.Info.ProjectCode, info.Info.Buyer)
  203. switch info.Pkey {
  204. case "pn":
  205. if len(PnAll[info.Pkey+info.Info.ProjectName]) > 0 {
  206. PnAll[info.Pkey+info.Info.ProjectName] = append(PnAll[info.Pkey+info.Info.ProjectName], id)
  207. }
  208. case "pc":
  209. if len(PcAll[info.Pkey+info.Info.ProjectCode]) > 0 {
  210. PcAll[info.Pkey+info.Info.ProjectCode] = append(PcAll[info.Pkey+info.Info.ProjectCode], id)
  211. }
  212. case "pb":
  213. if len(PbAll[info.Pkey+info.Info.Buyer]) > 0 {
  214. PbAll[info.Pkey+info.Info.Buyer] = append(PbAll[info.Pkey+info.Info.Buyer], id)
  215. }
  216. }
  217. } else {
  218. //新增项目
  219. id := newProjectInc(
  220. info.Data,
  221. map[string]interface{}{
  222. "meger_sflag": "normal",
  223. },
  224. time.Now().Unix(),
  225. info,
  226. )
  227. log.Println("新增项目", info.ProjectName, info.ProjectCode, info.Buyer)
  228. if len((*info).ProjectName) > 0 {
  229. if PnAll["pn_"+info.ProjectName] != nil {
  230. PnAll["pn_"+info.ProjectName] = append(PnAll["pn_"+info.ProjectName], id)
  231. } else {
  232. PnAll["pn_"+info.ProjectName] = []string{id}
  233. }
  234. }
  235. if len((*info).ProjectCode) > 0 {
  236. if PcAll["pc_"+info.ProjectCode] != nil {
  237. PcAll["pc_"+info.ProjectCode] = append(PcAll["pc_"+info.ProjectCode], id)
  238. } else {
  239. PcAll["pc_"+info.ProjectCode] = []string{id}
  240. }
  241. }
  242. if len((*info).Buyer) > 0 {
  243. if PbAll["pb_"+info.Buyer] != nil {
  244. PbAll["pb_"+info.Buyer] = append(PbAll["pb_"+info.Buyer], id)
  245. } else {
  246. PbAll["pb_"+info.Buyer] = []string{id}
  247. }
  248. }
  249. }
  250. }
  251. }
  252. func compareScoreMeger(ktype string, pids []string, info *Info) {
  253. var projects []*ProjectInfo
  254. for _, id := range pids {
  255. var projectInfo *ProjectInfo
  256. if pinfo, b := MQFW.FindById(projectColl, id, nil); b {
  257. bys, _ := json.Marshal(pinfo)
  258. json.Unmarshal(bys, &projectInfo)
  259. if projectInfo == nil {
  260. continue
  261. }
  262. //拼装projectInfo对象
  263. projectInfo.Id = projectInfo.IdInc
  264. projects = append(projects, projectInfo)
  265. }
  266. }
  267. if info.MererInc == Select3To1 {
  268. for _, project := range projects {
  269. score3Select1Inc(ktype, project, info)
  270. }
  271. }
  272. if info.MererInc == Select3To2 {
  273. for _, project := range projects {
  274. score3Select2Inc(ktype, project, info)
  275. }
  276. }
  277. }
  278. //3选2打分
  279. func score3Select2Inc(ktype string, pinfo *ProjectInfo, thisinfo *Info) {
  280. defer qu.Catch()
  281. rsInfos := InfoRScore[thisinfo.Id]
  282. if rsInfos == nil {
  283. rsInfos = []*RScoreInfo{}
  284. }
  285. rsinfo := &RScoreInfo{Id: thisinfo.Id, Info: thisinfo, Pid: pinfo.Id, Pinfo: pinfo}
  286. rsinfo.BuyerType, rsinfo.Score = fieldPCBScore(thisinfo.Buyer, pinfo.Buyer, rsinfo.BuyerType, rsinfo.Score)
  287. if len(thisinfo.Buyer) > 0 {
  288. rsinfo.ProjectNameType, rsinfo.Score = fieldPCBScore(thisinfo.ProjectName, pinfo.ProjectName, rsinfo.ProjectNameType, rsinfo.Score)
  289. rsinfo.ProjectCodeType, rsinfo.Score = fieldPCBScore(thisinfo.ProjectCode, pinfo.ProjectCode, rsinfo.ProjectCodeType, rsinfo.Score)
  290. } else { //无采购单位,打分考虑长度
  291. if len([]rune(thisinfo.ProjectName)) > MegerFieldsLen.ProjectNamelen {
  292. rsinfo.ProjectNameType, rsinfo.Score = fieldPCBScore(thisinfo.ProjectName, pinfo.ProjectName, rsinfo.ProjectNameType, rsinfo.Score)
  293. } else {
  294. rsinfo.ProjectNameType = "D"
  295. }
  296. if len(thisinfo.ProjectCode) > MegerFieldsLen.ProjectCodelen {
  297. rsinfo.ProjectCodeType, rsinfo.Score = fieldPCBScore(thisinfo.ProjectCode, pinfo.ProjectCode, rsinfo.ProjectCodeType, rsinfo.Score)
  298. } else {
  299. rsinfo.ProjectCodeType = "D"
  300. }
  301. }
  302. //省市打分
  303. if thisinfo.Area != "A" && thisinfo.Area != "全国" && pinfo.Area != "A" && pinfo.Area != "全国" {
  304. if thisinfo.Area == pinfo.Area && thisinfo.City == pinfo.City {
  305. rsinfo.Score += 2
  306. } else {
  307. rsinfo.Score -= 1
  308. }
  309. } else {
  310. rsinfo.Score += 1
  311. }
  312. //代理机构打分
  313. if len([]rune(pinfo.Agency)) > 0 {
  314. if thisinfo.Agency == pinfo.Agency { //A
  315. rsinfo.Score += 2
  316. } else if strings.Index(pinfo.Agency, thisinfo.Agency) > -1 || strings.Index(thisinfo.Agency, pinfo.Agency) > -1 { //B
  317. rsinfo.Score += 1
  318. } else {
  319. if len(thisinfo.Agency) < 1 { //E
  320. rsinfo.Score -= 1
  321. } else { //C
  322. rsinfo.Score -= 2
  323. }
  324. }
  325. } else { //D不计分
  326. //
  327. }
  328. rsinfo.Pkey = ktype
  329. rsinfo.Cresult = fmt.Sprintf("%s%s%s", rsinfo.BuyerType, rsinfo.ProjectNameType, rsinfo.ProjectCodeType)
  330. ThreeToLock.Lock()
  331. if ThreeToTow[rsinfo.Cresult] {
  332. rsInfos = append(rsInfos, rsinfo)
  333. InfoRScore[thisinfo.Id] = rsInfos
  334. }
  335. ThreeToLock.Unlock()
  336. }
  337. //3选1打分
  338. func score3Select1Inc(ktype string, pinfo *ProjectInfo, thisinfo *Info) {
  339. defer qu.Catch()
  340. rsInfos := InfoRScore[thisinfo.Id]
  341. if rsInfos == nil {
  342. rsInfos = []*RScoreInfo{}
  343. }
  344. rsinfo := &RScoreInfo{Id: thisinfo.Id, Info: thisinfo, Pid: pinfo.Id, Pinfo: pinfo}
  345. if ktype == "pn" { //比较字段项目名称
  346. if len(pinfo.ProjectName) > 0 {
  347. if thisinfo.ProjectName == pinfo.ProjectName { //A
  348. rsinfo.Score += 2
  349. rsinfo.ProjectNameType = "A"
  350. } else if strings.Index(pinfo.ProjectName, thisinfo.ProjectName) > -1 || strings.Index(thisinfo.ProjectName, pinfo.ProjectName) > -1 { //B
  351. rsinfo.Score += 1
  352. rsinfo.ProjectNameType = "B"
  353. } else { //C
  354. rsinfo.Score -= 2
  355. rsinfo.ProjectNameType = "C"
  356. }
  357. } else { //D不计分
  358. rsinfo.ProjectNameType = "D"
  359. }
  360. }
  361. if ktype == "pc" { //比较字段项目编号
  362. if len(pinfo.ProjectCode) > 0 {
  363. if thisinfo.ProjectCode == pinfo.ProjectCode { //A
  364. rsinfo.Score += 2
  365. rsinfo.ProjectCodeType = "A"
  366. } else if strings.Index(pinfo.ProjectCode, thisinfo.ProjectCode) > -1 || strings.Index(thisinfo.ProjectCode, pinfo.ProjectCode) > -1 { //B
  367. rsinfo.Score += 1
  368. rsinfo.ProjectCodeType = "B"
  369. } else { //C
  370. rsinfo.Score -= 2
  371. rsinfo.ProjectCodeType = "C"
  372. }
  373. } else { //D不计分
  374. rsinfo.ProjectCodeType = "D"
  375. }
  376. }
  377. if thisinfo.Area != "A" && thisinfo.Area != "全国" && pinfo.Area != "A" && pinfo.Area != "全国" {
  378. if thisinfo.Area == pinfo.Area && thisinfo.City == pinfo.City {
  379. rsinfo.Score += 2
  380. rsinfo.AreaType = "A"
  381. } else {
  382. rsinfo.Score -= 1
  383. rsinfo.AreaType = "C"
  384. }
  385. } else {
  386. rsinfo.Score += 1
  387. rsinfo.AreaType = "B"
  388. }
  389. if len([]rune(pinfo.Agency)) > 0 {
  390. if thisinfo.Agency == pinfo.Agency { //A
  391. rsinfo.Score += 2
  392. rsinfo.AgencyType = "A"
  393. } else if strings.Index(pinfo.Agency, thisinfo.Agency) > -1 || strings.Index(thisinfo.Agency, pinfo.Agency) > -1 { //B
  394. rsinfo.Score += 1
  395. rsinfo.AgencyType = "B"
  396. } else {
  397. if len(thisinfo.Agency) < 1 { //E
  398. rsinfo.Score -= 1
  399. rsinfo.AgencyType = "E"
  400. } else { //C
  401. rsinfo.Score -= 2
  402. rsinfo.AgencyType = "C"
  403. }
  404. }
  405. } else { //D不计分
  406. rsinfo.AgencyType = "D"
  407. }
  408. rsinfo.Pkey = ktype
  409. rsinfo.Cresult = fmt.Sprintf("%s%s%s%s", rsinfo.ProjectNameType, rsinfo.ProjectCodeType, rsinfo.AreaType, rsinfo.AgencyType)
  410. ThreeToLock.Lock()
  411. if ThreeToOne[rsinfo.Cresult] {
  412. rsInfos = append(rsInfos, rsinfo)
  413. InfoRScore[thisinfo.Id] = rsInfos
  414. }
  415. ThreeToLock.Unlock()
  416. }
  417. //判断是否合并项目、并确定打分流程
  418. func isMegerProjectAndProcess(tmp map[string]interface{}) (b bool, res int) {
  419. b = false
  420. pcbv := PCBVal(tmp)
  421. bNormalScore := true
  422. if checkInfoAlter(tmp) && pcbv.Val < 1 {
  423. bNormalScore = false
  424. res = InvalidInfo //无效信息,打标记
  425. }
  426. if bNormalScore {
  427. if pcbv.Buyer {
  428. if pcbv.PnameLen > 0 || pcbv.PcodeLen > 0 {
  429. res = Select3To2 //3选2打分
  430. b = true
  431. } else {
  432. res = AloneProject //生成核查新项目
  433. }
  434. } else {
  435. if pcbv.PnameLen > 0 {
  436. if pcbv.PcodeLen > 0 {
  437. res = Select3To2 //3选2打分
  438. b = true
  439. } else {
  440. if pcbv.PnameLen > MegerFieldsLen.ProjectNamelen {
  441. if pcbv.Agency && pcbv.Area {
  442. res = Select3To1 //3选1打分
  443. b = true
  444. } else {
  445. res = AloneProject //生成核查新项目
  446. }
  447. } else {
  448. res = AloneProject //生成核查新项目
  449. }
  450. }
  451. } else {
  452. if pcbv.Pcode {
  453. if pcbv.PcodeLen > MegerFieldsLen.ProjectCodelen {
  454. if pcbv.Agency && pcbv.Area {
  455. res = Select3To1 //3选1打分
  456. b = true
  457. } else {
  458. res = AloneProject //生成核查新项目
  459. }
  460. } else {
  461. res = AloneProject //生成核查新项目
  462. }
  463. } else {
  464. res = InvalidInfo //无效信息,打标记
  465. }
  466. }
  467. }
  468. }
  469. return
  470. }
  471. //新增项目
  472. func newProjectInc(tmp, mess map[string]interface{}, pipc int64, thisinfo *Info) (id string) {
  473. id = InsertProject(thisinfo.NewPNKey, tmp, mess, pipc, thisinfo)
  474. sflag := qu.ObjToString(mess["meger_sflag"])
  475. if sflag == "alone" {
  476. du.Debug("新增项目,不参与对比", id)
  477. }
  478. return id
  479. }
  480. //更新项目
  481. func updateinfoInc(thisinfo *Info, tmp map[string]interface{}, pInfo *ProjectInfo) string {
  482. updateid := pInfo.Id
  483. set := map[string]interface{}{}
  484. res, bres := MQFW.FindById(projectColl, pInfo.Id, `{"list":0}`)
  485. EqInfoUpdate(thisinfo, pInfo)
  486. if bres && res != nil && *res != nil {
  487. set["topscopeclass"] = pInfo.Topscopeclass
  488. set["subscopeclass"] = pInfo.Subscopeclass
  489. s_subscopeclass := strings.Join(pInfo.Subscopeclass, ",")
  490. if len(s_subscopeclass) > 0 {
  491. s_subscopeclass = "," + s_subscopeclass + ","
  492. }
  493. set["s_subscopeclass"] = s_subscopeclass
  494. s_winner := strings.Join(pInfo.Winners, ",")
  495. if len(s_winner) > 0 {
  496. s_winner = "," + s_winner + ","
  497. }
  498. set["s_winner"] = s_winner
  499. if pInfo.Buyerperson != "" && pInfo.Buyertel != "" {
  500. set["buyerperson"] = pInfo.Buyerperson
  501. set["buyertel"] = pInfo.Buyertel
  502. }
  503. if pInfo.Buyerclass != "" {
  504. set["buyerclass"] = pInfo.Buyerclass
  505. }
  506. if pInfo.District != "" {
  507. set["district"] = pInfo.District
  508. }
  509. if pInfo.Bidopentime > 0 {
  510. set["bidopentime"] = pInfo.Bidopentime
  511. }
  512. if len(pInfo.Winnerorder) > 0 {
  513. set["winnerorder"] = pInfo.Winnerorder
  514. }
  515. if thisinfo.HasPackage {
  516. set["multipackage"] = 1
  517. } else {
  518. set["multipackage"] = 0
  519. }
  520. e := InitEL(qu.ObjToString((*res)["extractpos"]))
  521. if thisinfo.dealtype == 1 {
  522. var sonpackage map[string]interface{}
  523. for _, obj := range tmp["package"].(map[string]interface{}) {
  524. sonpackage, _ = obj.(map[string]interface{})
  525. }
  526. for _, v2 := range []string{"budget", "budget_w", "winner", "winner_w", "bidstatus", "bidstatus_w"} {
  527. if sonpackage[v2] != nil {
  528. tmp[v2] = sonpackage[v2]
  529. }
  530. }
  531. }
  532. e.fieldpriority(&tmp, res, &set)
  533. set["extractpos"] = e.GetVal()
  534. if thisinfo.HasPackage { //多包处理
  535. p1, _ := (*res)["package"].(map[string]interface{})
  536. p2, _ := tmp["package"].(map[string]interface{})
  537. if p2 != nil {
  538. if p1 != nil {
  539. for pk2, pv2 := range p2 {
  540. if p1[pk2] != nil { //合并
  541. item1, _ := p1[pk2].(map[string]interface{})
  542. item2, _ := pv2.(map[string]interface{})
  543. if item1 != nil && item2 != nil { //原始项
  544. for ik1, iv1 := range item2 {
  545. if item1[ik1] == nil {
  546. item1[ik1] = iv1
  547. }
  548. }
  549. }
  550. } else {
  551. p1[pk2] = pv2
  552. }
  553. }
  554. } else {
  555. p1 = p2
  556. }
  557. }
  558. set["package"] = p1
  559. }
  560. //中标候选人合并
  561. update := map[string]interface{}{}
  562. if len(set) > 0 {
  563. update["$set"] = set
  564. }
  565. //保留原数据吧
  566. push := NewPushInfo(tmp)
  567. for tkey, _ := range extractpos {
  568. if tmp[tkey] != nil {
  569. push[tkey] = tmp[tkey]
  570. }
  571. }
  572. update["$push"] = map[string]interface{}{
  573. "list": push,
  574. }
  575. if len(update) > 0 {
  576. MQFW.Update(projectColl, map[string]interface{}{
  577. "_id": qu.StringTOBsonId(pInfo.Id),
  578. }, &update, false, false)
  579. }
  580. }
  581. return updateid
  582. }