main.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. package main
  2. /**
  3. 招标信息判重
  4. **/
  5. import (
  6. "encoding/json"
  7. "flag"
  8. "fmt"
  9. "log"
  10. mu "mfw/util"
  11. "net"
  12. "os"
  13. "qfw/util"
  14. "qfw/util/mongodb"
  15. "regexp"
  16. "sync"
  17. "time"
  18. )
  19. var (
  20. Sysconfig map[string]interface{} //配置文件
  21. mconf map[string]interface{} //mongodb配置信息
  22. mgo *mongodb.MongodbSim //mongodb操作对象
  23. extract string
  24. udpclient mu.UdpClient //udp对象
  25. nextNode []map[string]interface{} //下节点数组
  26. dupdays = 5 //初始化判重范围
  27. DM *datamap //
  28. HM *historymap //判重数据
  29. lastid = ""
  30. /*
  31. 5da3f31aa5cb26b9b798d3aa
  32. */
  33. //正则筛选相关
  34. FilterRegTitle = regexp.MustCompile("^_$")
  35. FilterRegTitle_1 = regexp.MustCompile("^_$")
  36. FilterRegTitle_2 = regexp.MustCompile("^_$")
  37. isMerger bool //是否合并
  38. threadNum int //线程数量
  39. SiteMap map[string]map[string]interface{} //站点map
  40. idtype, sid, eid string //测试人员判重使用
  41. )
  42. func init() {
  43. flag.StringVar(&lastid, "id", "", "最后加载id") //以小于等于此id开始加载最近几天的数据
  44. flag.StringVar(&sid, "sid", "", "开始id")
  45. flag.StringVar(&eid, "eid", "", "结束id")
  46. flag.StringVar(&idtype, "idtype", "", "id类型,默认ObjectId:0,String:1")
  47. flag.Parse()
  48. //172.17.145.163:27080
  49. util.ReadConfig(&Sysconfig)
  50. nextNode = util.ObjArrToMapArr(Sysconfig["nextNode"].([]interface{}))
  51. mconf = Sysconfig["mongodb"].(map[string]interface{})
  52. mgo = &mongodb.MongodbSim{
  53. MongodbAddr: mconf["addr"].(string),
  54. DbName: mconf["db"].(string),
  55. Size: util.IntAllDef(mconf["pool"], 10),
  56. }
  57. extract = mconf["extract"].(string)
  58. mgo.InitPool()
  59. //测试可以临时注释
  60. dupdays = util.IntAllDef(Sysconfig["dupdays"], 3)
  61. //加载数据
  62. DM = NewDatamap(dupdays, lastid)
  63. FilterRegTitle = regexp.MustCompile(util.ObjToString(Sysconfig["specialwords"]))
  64. FilterRegTitle_1 = regexp.MustCompile(util.ObjToString(Sysconfig["specialtitle_1"]))
  65. FilterRegTitle_2 = regexp.MustCompile(util.ObjToString(Sysconfig["specialtitle_2"]))
  66. isMerger = Sysconfig["isMerger"].(bool)
  67. threadNum = util.IntAllDef(Sysconfig["threads"], 1)
  68. //站点配置
  69. site := mconf["site"].(map[string]interface{})
  70. SiteMap = make(map[string]map[string]interface{}, 0)
  71. start := int(time.Now().Unix())
  72. sess_site := mgo.GetMgoConn()
  73. defer sess_site.Close()
  74. res_site := sess_site.DB(site["dbname"].(string)).C(site["coll"].(string)).Find(nil).Sort("_id").Iter()
  75. for site_dict := make(map[string]interface{}); res_site.Next(&site_dict); {
  76. data_map := map[string]interface{}{
  77. "area": util.ObjToString(site_dict["area"]),
  78. "city": util.ObjToString(site_dict["city"]),
  79. "district": util.ObjToString(site_dict["district"]),
  80. "sitetype": util.ObjToString(site_dict["sitetype"]),
  81. "level": util.ObjToString(site_dict["level"]),
  82. }
  83. SiteMap[util.ObjToString(site_dict["site"])] = data_map
  84. }
  85. fmt.Printf("用时:%d秒,%d个", int(time.Now().Unix())-start, len(SiteMap))
  86. }
  87. func main() {
  88. go checkMapJob()
  89. updport := Sysconfig["udpport"].(string)
  90. udpclient = mu.UdpClient{Local: updport, BufSize: 1024}
  91. udpclient.Listen(processUdpMsg)
  92. log.Println("Udp服务监听", updport)
  93. time.Sleep(99999 * time.Hour)
  94. }
  95. //测试组人员使用
  96. func mainT() {
  97. //sid = "568551000000000000000000"
  98. //eid = "5e0f65000000000000000000"
  99. mapinfo := map[string]interface{}{}
  100. if sid == "" || eid == "" {
  101. log.Println("sid,eid参数不能为空")
  102. os.Exit(0)
  103. }
  104. mapinfo["gtid"] = sid
  105. mapinfo["lteid"] = eid
  106. mapinfo["stop"] = "true"
  107. task([]byte{}, mapinfo)
  108. time.Sleep(5 * time.Second)
  109. }
  110. func processUdpMsg(act byte, data []byte, ra *net.UDPAddr) {
  111. fmt.Println("接受的段数据")
  112. switch act {
  113. case mu.OP_TYPE_DATA: //上个节点的数据
  114. //从表中开始处理
  115. var mapInfo map[string]interface{}
  116. err := json.Unmarshal(data, &mapInfo)
  117. log.Println("err:", err, "mapInfo:", mapInfo)
  118. if err != nil {
  119. udpclient.WriteUdp([]byte("err:"+err.Error()), mu.OP_NOOP, ra)
  120. } else if mapInfo != nil {
  121. taskType := util.ObjToString(mapInfo["stype"])
  122. if taskType == "historyTask" {
  123. //更新流程
  124. go historyTask(data, mapInfo)
  125. } else if taskType == "normalTask" {
  126. //判重流程
  127. go task(data, mapInfo)
  128. } else {
  129. //其他
  130. go task(data, mapInfo)
  131. }
  132. key, _ := mapInfo["key"].(string)
  133. if key == "" {
  134. key = "udpok"
  135. }
  136. udpclient.WriteUdp([]byte(key), mu.OP_NOOP, ra)
  137. }
  138. case mu.OP_NOOP: //下个节点回应
  139. ok := string(data)
  140. if ok != "" {
  141. log.Println("ok:", ok)
  142. udptaskmap.Delete(ok)
  143. }
  144. }
  145. }
  146. //开始判重程序
  147. func task(data []byte, mapInfo map[string]interface{}) {
  148. fmt.Println("开始数据判重")
  149. defer util.Catch()
  150. //区间id
  151. sess := mgo.GetMgoConn()
  152. defer mgo.DestoryMongoConn(sess)
  153. var q map[string]interface{}
  154. if idtype == "1" {
  155. q = map[string]interface{}{
  156. "_id": map[string]interface{}{
  157. "$gt": mapInfo["gtid"].(string),
  158. "$lte": mapInfo["lteid"].(string),
  159. },
  160. }
  161. } else {
  162. q = map[string]interface{}{
  163. "_id": map[string]interface{}{
  164. "$gt": util.StringTOBsonId(mapInfo["gtid"].(string)),
  165. "$lte": util.StringTOBsonId(mapInfo["lteid"].(string)),
  166. },
  167. }
  168. }
  169. log.Println(extract,mgo.DbName,q)
  170. it := sess.DB(mgo.DbName).C(extract).Find(&q).Sort("publishtime").Iter()
  171. updateExtract := [][]map[string]interface{}{}
  172. log.Println("线程数:",threadNum)
  173. pool := make(chan bool, threadNum)
  174. wg := &sync.WaitGroup{}
  175. //mapLock := &sync.Mutex{}
  176. n, repeateN := 0, 0
  177. for tmp := make(map[string]interface{}); it.Next(&tmp); n++ {
  178. if n%10000 == 0 {
  179. log.Println("current:", n, tmp["_id"], "repeateN:", repeateN)
  180. }
  181. pool <- true
  182. wg.Add(1)
  183. go func(tmp map[string]interface{}) {
  184. defer func() {
  185. <-pool
  186. wg.Done()
  187. }()
  188. info := NewInfo(tmp)
  189. //是否为无效数据
  190. if invalidData(info.buyer, info.projectname, info.projectcode) {
  191. updateExtract = append(updateExtract, []map[string]interface{}{
  192. map[string]interface{}{
  193. "_id": tmp["_id"],
  194. },
  195. map[string]interface{}{
  196. "$set": map[string]interface{}{
  197. "repeat": -1,
  198. },
  199. },
  200. })
  201. if len(updateExtract) > 500 {
  202. mgo.UpdateBulk(extract, updateExtract...)
  203. updateExtract = [][]map[string]interface{}{}
  204. }
  205. } else {
  206. b, source, reason := DM.check(info)
  207. if b { //有重复,生成更新语句,更新抽取和更新招标
  208. repeateN++
  209. var mergeArr = []int64{} //更改合并数组记录
  210. var newData = &Info{} //更换新的数据池数据
  211. var id_map = map[string]interface{}{}
  212. repeat_id := source.id
  213. id_map["_id"] = util.StringTOBsonId(info.id)
  214. if isMerger {
  215. //需要合并相关操作-合并操作--评功权重打分-合并完替换原始数据池
  216. basic_bool := basicDataScore(source, info)
  217. if basic_bool {
  218. //已原始数据为标准-对比数据打判重标签
  219. newData, mergeArr = mergeDataFields(source, info)
  220. DM.replaceSourceData(newData, source.id) //替换
  221. id_map["_id"] = util.StringTOBsonId(source.id)
  222. repeat_id = source.id
  223. } else {
  224. //已对比数据为标准 ,数据池的数据打判重标签
  225. newData, mergeArr = mergeDataFields(info, source)
  226. DM.replaceSourceData(newData, source.id) //替换
  227. id_map["_id"] = util.StringTOBsonId(info.id)
  228. repeat_id = info.id
  229. }
  230. }
  231. var update_map = map[string]interface{}{
  232. "$set": map[string]interface{}{
  233. "repeat_reason": reason,
  234. "repeat": 1,
  235. "repeatid": repeat_id,
  236. },
  237. }
  238. if isMerger {
  239. if len(newData.mergemap) > 0 {
  240. update_map["$set"].(map[string]interface{})["merge"] = newData.mergemap
  241. }
  242. //更新合并后的数据
  243. for _, value := range mergeArr {
  244. if value == 1 {
  245. update_map["$set"].(map[string]interface{})["area"] = newData.area
  246. update_map["$set"].(map[string]interface{})["city"] = newData.city
  247. } else if value == 2 {
  248. update_map["$set"].(map[string]interface{})["projectname"] = newData.projectname
  249. } else if value == 3 {
  250. update_map["$set"].(map[string]interface{})["projectcode"] = newData.projectcode
  251. } else if value == 4 {
  252. update_map["$set"].(map[string]interface{})["buyer"] = newData.buyer
  253. } else if value == 5 {
  254. update_map["$set"].(map[string]interface{})["budget"] = newData.budget
  255. } else if value == 6 {
  256. update_map["$set"].(map[string]interface{})["winner"] = newData.winner
  257. } else if value == 7 {
  258. update_map["$set"].(map[string]interface{})["bidamount"] = newData.bidamount
  259. } else if value == 8 {
  260. update_map["$set"].(map[string]interface{})["bidopentime"] = newData.bidopentime
  261. } else {
  262. }
  263. }
  264. }
  265. //构建数据库更新用到的
  266. updateExtract = append(updateExtract, []map[string]interface{}{
  267. id_map,
  268. update_map,
  269. })
  270. }
  271. }
  272. }(tmp)
  273. if len(updateExtract) > 500 {
  274. mgo.UpdateBulk(extract, updateExtract...)
  275. updateExtract = [][]map[string]interface{}{}
  276. }
  277. tmp = make(map[string]interface{})
  278. }
  279. wg.Wait()
  280. if len(updateExtract) > 0 {
  281. mgo.UpdateBulk(extract, updateExtract...)
  282. //mgo.UpdateBulk(bidding, updateBidding...)
  283. }
  284. log.Println("this task over.", n, "repeateN:", repeateN, mapInfo["stop"])
  285. //任务完成,开始发送广播通知下面节点
  286. if n > repeateN && mapInfo["stop"] == nil {
  287. for _, to := range nextNode {
  288. sid, _ := mapInfo["gtid"].(string)
  289. eid, _ := mapInfo["lteid"].(string)
  290. key := sid + "-" + eid + "-" + util.ObjToString(to["stype"])
  291. by, _ := json.Marshal(map[string]interface{}{
  292. "gtid": sid,
  293. "lteid": eid,
  294. "stype": util.ObjToString(to["stype"]),
  295. "key": key,
  296. })
  297. addr := &net.UDPAddr{
  298. IP: net.ParseIP(to["addr"].(string)),
  299. Port: util.IntAll(to["port"]),
  300. }
  301. node := &udpNode{by, addr, time.Now().Unix(), 0}
  302. udptaskmap.Store(key, node)
  303. udpclient.WriteUdp(by, mu.OP_TYPE_DATA, addr)
  304. }
  305. }
  306. }
  307. //支持历史更新
  308. func historyTask(data []byte, mapInfo map[string]interface{}) {
  309. fmt.Println("开始取历史时间段")
  310. defer util.Catch()
  311. sess := mgo.GetMgoConn()
  312. defer mgo.DestoryMongoConn(sess)
  313. q := map[string]interface{}{
  314. "_id": map[string]interface{}{
  315. "$gt": util.StringTOBsonId(mapInfo["gtid"].(string)),
  316. "$lte": util.StringTOBsonId(mapInfo["lteid"].(string)),
  317. },
  318. }
  319. it := sess.DB(mgo.DbName).C(extract).Find(&q).Iter()
  320. minTime, maxTime := int64(0), int64(0)
  321. for tmp := make(map[string]interface{}); it.Next(&tmp); {
  322. //取出最大最小时间
  323. if minTime == 0 || maxTime == 0 {
  324. minTime = util.Int64All(tmp["comeintime"])
  325. maxTime = util.Int64All(tmp["comeintime"])
  326. } else {
  327. t := util.Int64All(tmp["comeintime"])
  328. if t < minTime && t != 0 {
  329. minTime = t
  330. }
  331. if t > maxTime && t != 0 {
  332. maxTime = t
  333. }
  334. }
  335. }
  336. fmt.Println("最小时间==", minTime, "最大时间==", maxTime)
  337. //最小时间== 1568087634 最大时间== 1568103381
  338. HM = NewHistorymap(util.ObjToString(mapInfo["gtid"]),
  339. util.ObjToString(mapInfo["lteid"]), minTime, maxTime)
  340. //return
  341. //开始判重...
  342. defer util.Catch()
  343. sess_task := mgo.GetMgoConn()
  344. defer mgo.DestoryMongoConn(sess_task)
  345. q_task := map[string]interface{}{
  346. "_id": map[string]interface{}{
  347. "$gt": util.StringTOBsonId(mapInfo["gtid"].(string)),
  348. "$lte": util.StringTOBsonId(mapInfo["lteid"].(string)),
  349. },
  350. }
  351. it_task := sess.DB(mgo.DbName).C(extract).Find(&q_task).Iter()
  352. updateExtract := [][]map[string]interface{}{}
  353. pool := make(chan bool, threadNum)
  354. wg := &sync.WaitGroup{}
  355. //mapLock := &sync.Mutex{}
  356. n, repeateN := 0, 0
  357. for tmp := make(map[string]interface{}); it_task.Next(&tmp); n++ {
  358. if n%10000 == 0 {
  359. log.Println("current:", n, tmp["_id"], "repeateN:", repeateN)
  360. }
  361. pool <- true
  362. wg.Add(1)
  363. go func(tmp map[string]interface{}) {
  364. defer func() {
  365. <-pool
  366. wg.Done()
  367. }()
  368. info := NewInfo(tmp)
  369. if invalidData(info.buyer, info.projectname, info.projectcode) {
  370. //mapLock.Lock()
  371. updateExtract = append(updateExtract, []map[string]interface{}{
  372. map[string]interface{}{
  373. "_id": tmp["_id"],
  374. },
  375. map[string]interface{}{
  376. "$set": map[string]interface{}{
  377. "repeat": -1,
  378. },
  379. },
  380. })
  381. if len(updateExtract) > 500 {
  382. mgo.UpdateBulk(extract, updateExtract...)
  383. updateExtract = [][]map[string]interface{}{}
  384. }
  385. //mapLock.Unlock()
  386. } else {
  387. b, source, reason := HM.checkHistory(info)
  388. if b { //有重复,生成更新语句,更新抽取和更新招标
  389. if reason == "未判重记录" {
  390. fmt.Println("未判重记录")
  391. //把info的数据判重的标签更换,并新增字段
  392. DM.replaceSourceData(info, info.id) //替换即添加
  393. updateExtract = append(updateExtract, []map[string]interface{}{
  394. map[string]interface{}{
  395. "_id": tmp["_id"],
  396. },
  397. map[string]interface{}{
  398. "$set": map[string]interface{}{
  399. "repeat": 0,
  400. "repeatid": -2,
  401. },
  402. },
  403. })
  404. } else {
  405. repeateN++
  406. var mergeArr = []int64{} //更改合并数组记录
  407. var newData = &Info{} //更换新的数据池数据
  408. var id_map = map[string]interface{}{}
  409. repeat_id := source.id
  410. id_map["_id"] = util.StringTOBsonId(info.id)
  411. if isMerger {
  412. //需要合并相关操作-合并操作--评功权重打分-合并完替换原始数据池
  413. basic_bool := basicDataScore(source, info)
  414. if basic_bool {
  415. //已原始数据为标准-对比数据打判重标签
  416. newData, mergeArr = mergeDataFields(source, info)
  417. DM.replaceSourceData(newData, source.id) //替换
  418. id_map["_id"] = util.StringTOBsonId(source.id)
  419. repeat_id = source.id
  420. } else {
  421. //已对比数据为标准 ,数据池的数据打判重标签
  422. newData, mergeArr = mergeDataFields(info, source)
  423. DM.replaceSourceData(newData, source.id) //替换
  424. id_map["_id"] = util.StringTOBsonId(info.id)
  425. repeat_id = info.id
  426. }
  427. }
  428. var update_map = map[string]interface{}{
  429. "$set": map[string]interface{}{
  430. "repeat_reason": reason,
  431. "repeat": 1,
  432. "repeatid": repeat_id,
  433. },
  434. }
  435. if isMerger {
  436. //合并记录
  437. if len(newData.mergemap) > 0 {
  438. update_map["$set"].(map[string]interface{})["merge"] = newData.mergemap
  439. }
  440. //更新合并后的数据
  441. for _, value := range mergeArr {
  442. if value == 1 {
  443. update_map["$set"].(map[string]interface{})["area"] = newData.area
  444. update_map["$set"].(map[string]interface{})["city"] = newData.city
  445. } else if value == 2 {
  446. update_map["$set"].(map[string]interface{})["projectname"] = newData.projectname
  447. } else if value == 3 {
  448. update_map["$set"].(map[string]interface{})["projectcode"] = newData.projectcode
  449. } else if value == 4 {
  450. update_map["$set"].(map[string]interface{})["buyer"] = newData.buyer
  451. } else if value == 5 {
  452. update_map["$set"].(map[string]interface{})["budget"] = newData.budget
  453. } else if value == 6 {
  454. update_map["$set"].(map[string]interface{})["winner"] = newData.winner
  455. } else if value == 7 {
  456. update_map["$set"].(map[string]interface{})["bidamount"] = newData.bidamount
  457. } else if value == 8 {
  458. update_map["$set"].(map[string]interface{})["bidopentime"] = newData.bidopentime
  459. } else {
  460. }
  461. }
  462. }
  463. //构建数据库更新用到的
  464. updateExtract = append(updateExtract, []map[string]interface{}{
  465. id_map,
  466. update_map,
  467. })
  468. }
  469. }
  470. }
  471. }(tmp)
  472. if len(updateExtract) > 500 {
  473. mgo.UpdateBulk(extract, updateExtract...)
  474. updateExtract = [][]map[string]interface{}{}
  475. }
  476. tmp = make(map[string]interface{})
  477. }
  478. wg.Wait()
  479. if len(updateExtract) > 0 {
  480. mgo.UpdateBulk(extract, updateExtract...)
  481. //mgo.UpdateBulk(bidding, updateBidding...)
  482. }
  483. log.Println("this task over.", n, "repeateN:", repeateN, mapInfo["stop"])
  484. //任务完成,开始发送广播通知下面节点
  485. if n > repeateN && mapInfo["stop"] == nil {
  486. for _, to := range nextNode {
  487. sid, _ := mapInfo["gtid"].(string)
  488. eid, _ := mapInfo["lteid"].(string)
  489. key := sid + "-" + eid + "-" + util.ObjToString(to["stype"])
  490. by, _ := json.Marshal(map[string]interface{}{
  491. "gtid": sid,
  492. "lteid": eid,
  493. "stype": util.ObjToString(to["stype"]),
  494. "key": key,
  495. })
  496. addr := &net.UDPAddr{
  497. IP: net.ParseIP(to["addr"].(string)),
  498. Port: util.IntAll(to["port"]),
  499. }
  500. node := &udpNode{by, addr, time.Now().Unix(), 0}
  501. udptaskmap.Store(key, node)
  502. udpclient.WriteUdp(by, mu.OP_TYPE_DATA, addr)
  503. }
  504. }
  505. }
  506. //合并字段
  507. func mergeDataFields(source *Info, info *Info) (*Info, []int64) {
  508. var mergeArr []int64
  509. mergeArr = make([]int64, 0)
  510. //1、城市
  511. if (source.area == "" || source.area == "全国") && info.area != "全国" && info.area != "" {
  512. var arrA []string
  513. if source.mergemap["area"] == nil {
  514. arrA = make([]string, 0)
  515. } else {
  516. arrA = source.mergemap["area"].([]string)
  517. }
  518. arrA = append(arrA, source.area)
  519. source.mergemap["area"] = arrA
  520. var arrC []string
  521. if source.mergemap["city"] == nil {
  522. arrC = make([]string, 0)
  523. } else {
  524. arrC = source.mergemap["city"].([]string)
  525. }
  526. arrC = append(arrC, source.city)
  527. source.mergemap["city"] = arrC
  528. source.area = info.area
  529. source.city = info.city
  530. mergeArr = append(mergeArr, 1)
  531. }
  532. //2、项目名称
  533. if source.projectname == "" && info.projectname != "" {
  534. var arr []string
  535. if source.mergemap["projectname"] == nil {
  536. arr = make([]string, 0)
  537. } else {
  538. arr = source.mergemap["projectname"].([]string)
  539. }
  540. arr = append(arr, source.projectname)
  541. source.mergemap["projectname"] = arr
  542. source.projectname = info.projectname
  543. mergeArr = append(mergeArr, 2)
  544. }
  545. //3、项目编号
  546. if source.projectcode == "" && info.projectcode != "" {
  547. var arr []string
  548. if source.mergemap["projectcode"] == nil {
  549. arr = make([]string, 0)
  550. } else {
  551. arr = source.mergemap["projectcode"].([]string)
  552. }
  553. arr = append(arr, source.projectcode)
  554. source.mergemap["projectcode"] = arr
  555. source.projectcode = info.projectcode
  556. mergeArr = append(mergeArr, 3)
  557. }
  558. //4、采购单位
  559. if source.buyer == "" && info.buyer != "" {
  560. var arr []string
  561. if source.mergemap["buyer"] == nil {
  562. arr = make([]string, 0)
  563. } else {
  564. arr = source.mergemap["buyer"].([]string)
  565. }
  566. arr = append(arr, source.buyer)
  567. source.mergemap["buyer"] = arr
  568. source.buyer = info.buyer
  569. mergeArr = append(mergeArr, 4)
  570. }
  571. //5、预算
  572. if source.budget == 0 && info.budget != 0 {
  573. var arr []float64
  574. if source.mergemap["budget"] == nil {
  575. arr = make([]float64, 0)
  576. } else {
  577. arr = source.mergemap["budget"].([]float64)
  578. }
  579. arr = append(arr, source.budget)
  580. source.mergemap["budget"] = arr
  581. source.budget = info.budget
  582. mergeArr = append(mergeArr, 5)
  583. }
  584. //6、中标单位
  585. if source.winner == "" && info.winner != "" {
  586. var arr []string
  587. if source.mergemap["winner"] == nil {
  588. arr = make([]string, 0)
  589. } else {
  590. arr = source.mergemap["winner"].([]string)
  591. }
  592. arr = append(arr, source.winner)
  593. source.mergemap["winner"] = arr
  594. source.winner = info.winner
  595. mergeArr = append(mergeArr, 6)
  596. }
  597. //7、中标金额
  598. if source.bidamount == 0 && info.bidamount != 0 {
  599. var arr []float64
  600. if source.mergemap["bidamount"] == nil {
  601. arr = make([]float64, 0)
  602. } else {
  603. arr = source.mergemap["bidamount"].([]float64)
  604. }
  605. arr = append(arr, source.bidamount)
  606. source.mergemap["bidamount"] = arr
  607. source.bidamount = info.bidamount
  608. mergeArr = append(mergeArr, 7)
  609. }
  610. //8、开标时间-地点
  611. if source.bidopentime == 0 && info.bidopentime != 0 {
  612. var arr []int64
  613. if source.mergemap["bidopentime"] == nil {
  614. arr = make([]int64, 0)
  615. } else {
  616. arr = source.mergemap["bidopentime"].([]int64)
  617. }
  618. arr = append(arr, source.bidopentime)
  619. source.mergemap["bidopentime"] = arr
  620. source.bidopentime = info.bidopentime
  621. mergeArr = append(mergeArr, 8)
  622. }
  623. //以上合并过于简单,待进一步优化
  624. return source, mergeArr
  625. }
  626. //权重评估
  627. func basicDataScore(v *Info, info *Info) bool {
  628. /*
  629. 权重评估
  630. 网站优先级判定规则:
  631. 1、中央>省>市>县区
  632. 2、政府采购>公共资源>采购单位官网>招标代理公司/平台
  633. */
  634. v_score, info_score := -1, -1
  635. dict_v := SiteMap[v.site]
  636. dict_info := SiteMap[info.site]
  637. //先判断level
  638. if dict_v != nil {
  639. v_level := util.ObjToString(dict_v["level"])
  640. if v_level == "中央" {
  641. v_score = 4
  642. } else if v_level == "省级" {
  643. v_score = 3
  644. } else if v_level == "市级" {
  645. v_score = 2
  646. } else if v_level == "县区" {
  647. v_score = 1
  648. } else if v_level == "" {
  649. } else {
  650. v_score = 0
  651. }
  652. }
  653. if dict_info != nil {
  654. info_level := util.ObjToString(dict_info["level"])
  655. if info_level == "中央" {
  656. info_score = 4
  657. } else if info_level == "省级" {
  658. info_score = 3
  659. } else if info_level == "市级" {
  660. info_score = 2
  661. } else if info_level == "县区" {
  662. info_score = 1
  663. } else if info_level == "" {
  664. } else {
  665. v_score = 0
  666. }
  667. }
  668. if v_score > info_score {
  669. return true
  670. }
  671. if v_score < info_score {
  672. return false
  673. }
  674. //判断sitetype
  675. if dict_v != nil {
  676. v_sitetype := util.ObjToString(dict_v["sitetype"])
  677. if v_sitetype == "政府采购" || v_sitetype == "政府门户" {
  678. v_score = 4
  679. } else if v_sitetype == "公共资源" {
  680. v_score = 3
  681. } else if v_sitetype == "官方网站" {
  682. v_score = 2
  683. } else if v_sitetype == "社会公共招标平台" || v_sitetype == "企业招标平台" {
  684. v_score = 1
  685. } else if v_sitetype == "" {
  686. } else {
  687. v_score = 0
  688. }
  689. }
  690. if dict_info != nil {
  691. info_sitetype := util.ObjToString(dict_info["sitetype"])
  692. if info_sitetype == "政府采购" || info_sitetype == "政府门户" {
  693. info_score = 4
  694. } else if info_sitetype == "公共资源" {
  695. info_score = 3
  696. } else if info_sitetype == "官方网站" {
  697. info_score = 2
  698. } else if info_sitetype == "社会公共招标平台" || info_sitetype == "企业招标平台" {
  699. info_score = 1
  700. } else if info_sitetype == "" {
  701. } else {
  702. info_score = 0
  703. }
  704. }
  705. if v_score > info_score {
  706. return true
  707. }
  708. if v_score < info_score {
  709. return false
  710. }
  711. //网站评估
  712. m, n := 0, 0
  713. if v.projectname != "" {
  714. m++
  715. }
  716. if v.buyer != "" {
  717. m++
  718. }
  719. if v.projectcode != "" {
  720. m++
  721. }
  722. if v.budget != 0 {
  723. m++
  724. }
  725. if v.bidamount != 0 {
  726. m++
  727. }
  728. if v.winner != "" {
  729. m++
  730. }
  731. if v.bidopentime != 0 {
  732. m++
  733. }
  734. if v.agencyaddr != "" {
  735. m++
  736. }
  737. if v.agency != "" {
  738. m = m + 2
  739. }
  740. if v.city != "" {
  741. m = m + 2
  742. }
  743. if info.projectname != "" {
  744. n++
  745. }
  746. if info.buyer != "" {
  747. n++
  748. }
  749. if info.projectcode != "" {
  750. n++
  751. }
  752. if info.budget != 0 {
  753. n++
  754. }
  755. if info.bidamount != 0 {
  756. n++
  757. }
  758. if info.winner != "" {
  759. n++
  760. }
  761. if info.bidopentime != 0 {
  762. n++
  763. }
  764. if info.agencyaddr != "" {
  765. n++
  766. }
  767. if info.agency != "" {
  768. n = n + 2
  769. }
  770. if info.city != "" {
  771. n = n + 2
  772. }
  773. if m > n {
  774. return true
  775. } else if m == n {
  776. if v.comeintime >= info.comeintime {
  777. return true
  778. } else {
  779. return false
  780. }
  781. } else {
  782. return false
  783. }
  784. }
  785. //无效数据
  786. func invalidData(d1 string, d2 string, d3 string) bool {
  787. var n int
  788. if d1 != "" {
  789. n++
  790. }
  791. if d2 != "" {
  792. n++
  793. }
  794. if d3 != "" {
  795. n++
  796. }
  797. if n == 0 {
  798. return true
  799. }
  800. return false
  801. }