init.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. package main
  2. import (
  3. "log"
  4. "math"
  5. mu "mfw/util"
  6. "qfw/util"
  7. "regexp"
  8. "sort"
  9. "strings"
  10. "sync"
  11. "go.mongodb.org/mongo-driver/bson/primitive"
  12. )
  13. var (
  14. Sysconfig map[string]interface{} //读取配置文件
  15. MongoTool, MgoBidding *MongodbSim //mongodb连接
  16. ExtractColl, ProjectColl, BackupColl, SiteColl string //抽取表、项目表、项目快照表、站点表
  17. Thread int //配置项线程数
  18. BlackList []interface{}
  19. BlaskListMap map[string]bool
  20. )
  21. var (
  22. //判断是日期
  23. _datereg = regexp.MustCompile("20[0-2][0-9][年-][0-9]{1,2}[月-][0-9]{1,2}[日-]([0-9]{1,2}时[0-9]{0,2})?")
  24. _numreg1 = regexp.MustCompile("^[0-9-]{1,8}$")
  25. _zimureg1 = regexp.MustCompile("^[a-zA-Z-]{1,7}$")
  26. _nzreg = regexp.MustCompile("^[0-9a-zA-Z-]+$")
  27. _hanreg = regexp.MustCompile(`^[\p{Han}::【】\\[\\]()()--、]+$`)
  28. replaceStr = regexp.MustCompile("(工程|采购|项目|[?!、【】()—()--]|栏标价|中标候选人|招标代理)")
  29. //判断带有分包、等特定词的
  30. pStr = regexp.MustCompile("(勘察|监理|施工|设计|验收|标段|分包|子包|[0-9A-Z]包|[一二三四五六七八九十0-9]批)")
  31. //判断包含数值
  32. nreg1 = regexp.MustCompile("[0-9]{2,}")
  33. //判断包含字母
  34. zreg1 = regexp.MustCompile("[a-zA-Z]{1,}")
  35. //判断包含汉字
  36. hreg1 = regexp.MustCompile(`[\p{Han}]+`)
  37. //判断项目编号是在10以内的纯数字结构
  38. numCheckPc = regexp.MustCompile("^[0-9-]{1,10}$")
  39. //仅初始化使用
  40. compareNoPass = map[string]bool{}
  41. compareAB = map[string]bool{}
  42. compareAB2D = map[string]bool{}
  43. compareABD = map[string]bool{}
  44. compareAB2CD = map[string]bool{}
  45. compareABCD = map[string]bool{}
  46. )
  47. func init() {
  48. util.ReadConfig(&Sysconfig)
  49. MongoTool = &MongodbSim{
  50. MongodbAddr: Sysconfig["mongodbServers"].(string),
  51. Size: util.IntAll(Sysconfig["mongodbPoolSize"]),
  52. DbName: Sysconfig["mongodbName"].(string),
  53. }
  54. MongoTool.InitPool()
  55. bidding, _ := Sysconfig["bidding"].(map[string]interface{})
  56. MgoBidding = &MongodbSim{
  57. MongodbAddr: bidding["addr"].(string),
  58. Size: util.IntAll(bidding["dbsize"]),
  59. DbName: bidding["dbname"].(string),
  60. }
  61. MgoBidding.InitPool()
  62. ExtractColl = Sysconfig["extractColl"].(string)
  63. ProjectColl = Sysconfig["projectColl"].(string)
  64. BackupColl = Sysconfig["projectColl"].(string) + "_back"
  65. SiteColl = Sysconfig["siteColl"].(string)
  66. Thread = util.IntAll(Sysconfig["thread"])
  67. //NextNode = Sysconfig["nextNode"].([]interface{})
  68. udpport, _ := Sysconfig["udpport"].(string)
  69. udpclient = mu.UdpClient{Local: udpport, BufSize: 1024}
  70. udpclient.Listen(processUdpMsg)
  71. log.Println("Udp服务监听", udpport)
  72. BlackList = Sysconfig["rp_blacklist"].([]interface{})
  73. BlaskListMap = make(map[string]bool)
  74. for _, v := range BlackList {
  75. BlaskListMap[util.ObjToString(v)] = true
  76. }
  77. initWinnerRegexp()
  78. initBuyerRegexp()
  79. initAgencyRegexp()
  80. //加载项目数据
  81. //---不能通过
  82. vm := []string{"C", "D"}
  83. for i := 0; i < 2; i++ {
  84. for j := 0; j < 2; j++ {
  85. for k := 0; k < 2; k++ {
  86. key := vm[i] + vm[j] + vm[k]
  87. compareNoPass[key] = true
  88. //fmt.Println(key)
  89. }
  90. }
  91. }
  92. //fmt.Println("-------------------")
  93. //三个元素一致 [AB][AB][AB],分值最高
  94. vm = []string{"A", "B"}
  95. for i := 0; i < 2; i++ {
  96. for j := 0; j < 2; j++ {
  97. for k := 0; k < 2; k++ {
  98. key := vm[i] + vm[j] + vm[k]
  99. compareAB[key] = true
  100. //fmt.Println(key)
  101. }
  102. }
  103. }
  104. //fmt.Println("-------------------", len(compareAB))
  105. //---至少两个一致,其他可能不存在
  106. //[AB][AB][ABD]
  107. //[AB][ABD][AB]
  108. vm = []string{"A", "B"}
  109. vm2 := []string{"A", "B", "D"}
  110. for i := 0; i < 2; i++ {
  111. for j := 0; j < 2; j++ {
  112. for k := 0; k < 3; k++ {
  113. key := vm[i] + vm[j] + vm2[k]
  114. if !compareAB[key] {
  115. compareAB2D[key] = true
  116. //fmt.Println(key)
  117. }
  118. }
  119. }
  120. }
  121. for i := 0; i < 2; i++ {
  122. for j := 0; j < 3; j++ {
  123. for k := 0; k < 2; k++ {
  124. key := vm[i] + vm2[j] + vm[k]
  125. if !compareAB[key] {
  126. compareAB2D[key] = true
  127. //fmt.Println(key)
  128. }
  129. }
  130. }
  131. }
  132. //fmt.Println("-------------------", len(compareAB2D))
  133. //---至少一个一致,其他可能不存在
  134. //[ABD][ABD][ABD] //已经删除DDD
  135. vm = []string{"A", "B", "D"}
  136. for i := 0; i < 3; i++ {
  137. for j := 0; j < 3; j++ {
  138. for k := 0; k < 3; k++ {
  139. key := vm[i] + vm[j] + vm[k]
  140. if !compareAB[key] && !compareAB2D[key] && !compareNoPass[key] {
  141. compareABD[key] = true
  142. //fmt.Println(key)
  143. }
  144. }
  145. }
  146. }
  147. //fmt.Println("-------------------", len(compareABD))
  148. //[AB][ABCD][AB]
  149. //[AB][AB][ABCD]
  150. vm = []string{"A", "B"}
  151. vm2 = []string{"A", "B", "C", "D"}
  152. for i := 0; i < 2; i++ {
  153. for j := 0; j < 4; j++ {
  154. for k := 0; k < 2; k++ {
  155. key := vm[i] + vm2[j] + vm[k]
  156. if !compareAB[key] && !compareAB2D[key] && !compareNoPass[key] && !compareABD[key] {
  157. compareAB2CD[key] = true
  158. //fmt.Println(key)
  159. }
  160. }
  161. }
  162. }
  163. for i := 0; i < 2; i++ {
  164. for j := 0; j < 2; j++ {
  165. for k := 0; k < 4; k++ {
  166. key := vm[i] + vm[j] + vm2[k]
  167. if !compareAB[key] && !compareAB2D[key] && !compareNoPass[key] && !compareABD[key] {
  168. compareAB2CD[key] = true
  169. //fmt.Println(key)
  170. }
  171. }
  172. }
  173. }
  174. //fmt.Println("-------------------", len(compareAB2CD))
  175. //[ABECD][ABECD][ABECD] //已经删除[CD][CD][CD] //这个要重点讨论
  176. vm = []string{"A", "B", "C", "D"}
  177. for i := 0; i < 4; i++ {
  178. for j := 0; j < 4; j++ {
  179. for k := 0; k < 4; k++ {
  180. key := vm[i] + vm[j] + vm[k]
  181. if !compareAB[key] && !compareAB2D[key] && !compareABD[key] && !compareNoPass[key] && !compareAB2CD[key] {
  182. compareABCD[key] = true
  183. //fmt.Println(key)
  184. }
  185. }
  186. }
  187. }
  188. }
  189. func CheckHanAndNum(str string) (b bool) {
  190. return nreg1.MatchString(str) && hreg1.MatchString(str)
  191. }
  192. func CheckZimuAndNum(str string) (b bool) {
  193. return zreg1.MatchString(str) && nreg1.MatchString(str)
  194. }
  195. type KeyMap struct {
  196. Lock sync.Mutex
  197. Map map[string]*Key
  198. }
  199. type ID struct {
  200. Id string
  201. Lock sync.Mutex
  202. P *ProjectInfo
  203. }
  204. type Key struct {
  205. Arr []string
  206. Lock sync.Mutex
  207. }
  208. type IdAndLock struct {
  209. Id string
  210. Lock sync.Mutex
  211. }
  212. func NewKeyMap() *KeyMap {
  213. return &KeyMap{
  214. Map: map[string]*Key{},
  215. Lock: sync.Mutex{},
  216. }
  217. }
  218. //招标信息实体类
  219. type Info struct {
  220. Id string `json:"_id"`
  221. Href string `json:"href"` //源地址
  222. Publishtime int64 `json:"publishtime"`
  223. Comeintime int64 `json:"comeintime"`
  224. Title string `json:"title"`
  225. TopType string `json:"toptype"`
  226. SubType string `json:"subtype"`
  227. ProjectName string `json:"projectname"`
  228. ProjectCode string `json:"projectcode"`
  229. ProjectScope string `json:"projectscope"`
  230. ContractCode string `json:"contractcode"`
  231. Buyer string `json:"buyer"`
  232. Buyerperson string `json:"buyerperson"`
  233. Buyertel string `json:"buyertel"`
  234. Agency string `json:"agency"`
  235. Area string `json:"area"`
  236. City string `json:"city"`
  237. District string `json:"district"`
  238. Infoformat int `json:"infoformat"`
  239. ReviewExperts []string `json:"review_experts"`
  240. Purchasing string `json:"purchasing"`
  241. WinnerOrder []map[string]interface{} `json:"winnerorder"`
  242. HasPackage bool // `json:"haspackage"`
  243. Package map[string]interface{} `json:"package"`
  244. //PNum string `json:"pnum"`
  245. Topscopeclass []string `json:"topscopeclass"`
  246. Subscopeclass []string `json:"subscopeclass"`
  247. Buyerclass string `json:"buyerclass"`
  248. Bidopentime int64 `json:"bidopentime"`
  249. Budget float64 `json:"budget"`
  250. Bidamount float64 `json:"bidamount"`
  251. Winners []string
  252. dealtype int
  253. PTC string //从标题中抽的项目编号
  254. pnbval int //项目名称、编号、采购单位存在的个数
  255. LenPC int //项目编号长度
  256. LenPN int //项目名称长度
  257. LenPTC int //标题抽的项目编号长度
  258. //以下三个元素做对比,计算包含时候使用
  259. PNBH int //0初始,+包含,-被包含
  260. PCBH int
  261. PTCBH int
  262. }
  263. //项目实体类
  264. type ProjectInfo struct {
  265. Id primitive.ObjectID `json:"_id"`
  266. FirstTime int64 `json:"firsttime,omitempty"` //项目的最早时间
  267. LastTime int64 `json:"lasttime,omitempty"` //项目的最后时间
  268. Ids []string `json:"ids,omitempty"`
  269. Topscopeclass []string `json:"topscopeclass,omitempty"`
  270. Subscopeclass []string `json:"subscopeclass,omitempty"` //子行业分类
  271. Winners []string `json:"s_winner,omitempty"` //中标人
  272. ProjectName string `json:"projectname,omitempty"` //项目名称
  273. ProjectCode string `json:"projectcode,omitempty"` //项目代码唯一(纯数字的权重低)
  274. ContractCode string `json:"contractcode,omitempty"` //项目编号
  275. Buyer string `json:"buyer,omitempty"` //采购单位唯一
  276. MPN []string `json:"mpn,omitempty"` //合并后多余的项目名称
  277. MPC []string `json:"mpc,omitempty"` //合并后多余的项目编号
  278. Buyerperson string `json:"buyerperson"` //采购联系人
  279. Buyertel string `json:"buyertel"` //采购联系人电话
  280. Agency string `json:"agency"` //代理机构
  281. Area string `json:"area"` //地区
  282. City string `json:"city"` //地市
  283. District string `json:"district"` //区县
  284. Bidstatus string `json:"bidstatus"` //
  285. Bidtype string `json:"bidtype"` //
  286. ReviewExperts []string `json:"review_experts"` // 项目评审专家
  287. Purchasing string `json:"purchasing"` // 标的物
  288. //HasPackage bool `json:"haspackage"` //是否有分包
  289. Package map[string]interface{} `json:"package,omitempty"` //分包的对比对象
  290. Buyerclass string `json:"buyerclass"` //采购单位分类
  291. Bidopentime int64 `json:"bidopentime,omitempty"` //开标时间
  292. // Zbtime int64 `json:"zbtime"` //招标时间
  293. Jgtime int64 `json:"jgtime"` //结果中标时间
  294. Zbtime int64 `json:"zbtime"` //招标时间
  295. Bidamount float64 `json:"bidamount,omitempty"` //中标金额
  296. Budget float64 `json:"budget,omitempty"` //预算
  297. Winnerorder []string `json:"winnerorder"` //中标候选人
  298. score int
  299. comStr string
  300. resVal, pjVal int
  301. InfoFiled map[string]InfoField `json:"infofield"` //逻辑处理需要的info字段
  302. Budgettag int `json:"budgettag"` //预算是否有效标记
  303. Bidamounttag int `json:"bidamounttag"` //中标金额是否有效标记
  304. }
  305. //存储部分招标信息字段,业务逻辑处理需要
  306. type InfoField struct {
  307. Budget float64 `json:"budget"`
  308. Bidamount float64 `json:"bidamount"`
  309. ContractCode string `json:"contractcode"`
  310. ProjectName string `json:"projectname"`
  311. ProjectCode string `json:"projectcode"`
  312. Bidstatus string `json:"bidstatus"`
  313. }
  314. //站点信息
  315. type Site struct {
  316. Id string `json:"_id"`
  317. Site string `json:"site"` //站点名字
  318. Area string `json:"area"` //省
  319. City string `json:"city"` //市
  320. District string `json:"district"` //区、县
  321. Domain string `json:"domain"` //地址
  322. Status int `json:"status"` //
  323. }
  324. //二分字符串查找
  325. func BinarySearch(s []string, k string) int {
  326. sort.Strings(s)
  327. lo, hi := 0, len(s)-1
  328. for lo <= hi {
  329. m := (lo + hi) >> 1
  330. if s[m] < k {
  331. lo = m + 1
  332. } else if s[m] > k {
  333. hi = m - 1
  334. } else {
  335. return m
  336. }
  337. }
  338. return -1
  339. }
  340. //计算文本相似度
  341. func CosineSimilar(srcWords1, dstWords1 string) float64 {
  342. srcWords, dstWords := strings.Split(srcWords1, ""), strings.Split(dstWords1, "")
  343. // get all words
  344. allWordsMap := make(map[string]int, 0)
  345. for _, word := range srcWords {
  346. if _, found := allWordsMap[word]; !found {
  347. allWordsMap[word] = 1
  348. } else {
  349. allWordsMap[word] += 1
  350. }
  351. }
  352. for _, word := range dstWords {
  353. if _, found := allWordsMap[word]; !found {
  354. allWordsMap[word] = 1
  355. } else {
  356. allWordsMap[word] += 1
  357. }
  358. }
  359. // stable the sort
  360. allWordsSlice := make([]string, 0)
  361. for word, _ := range allWordsMap {
  362. allWordsSlice = append(allWordsSlice, word)
  363. }
  364. // assemble vector
  365. srcVector := make([]int, len(allWordsSlice))
  366. dstVector := make([]int, len(allWordsSlice))
  367. for _, word := range srcWords {
  368. if index := BinarySearch(allWordsSlice, word); index != -1 {
  369. srcVector[index] += 1
  370. }
  371. }
  372. for _, word := range dstWords {
  373. if index := BinarySearch(allWordsSlice, word); index != -1 {
  374. dstVector[index] += 1
  375. }
  376. }
  377. // calc cos
  378. numerator := float64(0)
  379. srcSq := 0
  380. dstSq := 0
  381. for i, srcCount := range srcVector {
  382. dstCount := dstVector[i]
  383. numerator += float64(srcCount * dstCount)
  384. srcSq += srcCount * srcCount
  385. dstSq += dstCount * dstCount
  386. }
  387. denominator := math.Sqrt(float64(srcSq * dstSq))
  388. v1 := numerator / denominator
  389. // if v1 > 0.6 {
  390. // log.Println(v1, srcWords1, dstWords1)
  391. // }
  392. return v1
  393. }
  394. func initWinnerRegexp() {
  395. winRegMap := Sysconfig["winner"].(map[string]interface{})
  396. preRegexps := winRegMap["pre_regexp"].([]interface{})
  397. backRegexps := winRegMap["back_regexp"].([]interface{})
  398. backRepRegexps := winRegMap["back_rep_regexp"].([]interface{})
  399. backBlack := winRegMap["blacklist"].([]interface{})
  400. var winPreRegexps []*regexp.Regexp
  401. for _, v := range preRegexps {
  402. reg := regexp.MustCompile("^" + v.(string))
  403. winPreRegexps = append(winPreRegexps, reg)
  404. }
  405. PreRegexp["winner"] = winPreRegexps
  406. var winBackRegexps []*regexp.Regexp
  407. for _, v := range backRegexps {
  408. reg := regexp.MustCompile(v.(string))
  409. winBackRegexps = append(winBackRegexps, reg)
  410. }
  411. BackRegexp["winner"] = winBackRegexps
  412. var winBackRepRegexps []RegexpInfo
  413. for _, v := range backRepRegexps {
  414. reps := strings.Split(v.(string), "#")
  415. if len(reps) > 1 {
  416. reg := RegexpInfo{
  417. regs: regexp.MustCompile(reps[0]),
  418. repstr: reps[1],
  419. }
  420. winBackRepRegexps = append(winBackRepRegexps, reg)
  421. }
  422. }
  423. BackRepRegexp["winner"] = winBackRepRegexps
  424. var winBlackRegexps []*regexp.Regexp
  425. for _, v := range backBlack {
  426. reg := regexp.MustCompile(v.(string))
  427. winBlackRegexps = append(winBlackRegexps, reg)
  428. }
  429. BlackRegexp["winner"] = winBlackRegexps
  430. }
  431. func initBuyerRegexp() {
  432. buyRegMap := Sysconfig["buyer"].(map[string]interface{})
  433. preRegexps := buyRegMap["pre_regexp"].([]interface{})
  434. backRegexps := buyRegMap["back_regexp"].([]interface{})
  435. backRepRegexps := buyRegMap["back_rep_regexp"].([]interface{})
  436. backBlack := buyRegMap["blacklist"].([]interface{})
  437. var winPreRegexps []*regexp.Regexp
  438. for _, v := range preRegexps {
  439. reg := regexp.MustCompile("^" + v.(string))
  440. winPreRegexps = append(winPreRegexps, reg)
  441. }
  442. PreRegexp["buyer"] = winPreRegexps
  443. var winBackRegexps []*regexp.Regexp
  444. for _, v := range backRegexps {
  445. reg := regexp.MustCompile(v.(string))
  446. winBackRegexps = append(winBackRegexps, reg)
  447. }
  448. BackRegexp["buyer"] = winBackRegexps
  449. var winBackRepRegexps []RegexpInfo
  450. for _, v := range backRepRegexps {
  451. reps := strings.Split(v.(string), "#")
  452. if len(reps) > 1 {
  453. reg := RegexpInfo{
  454. regs: regexp.MustCompile(reps[0]),
  455. repstr: reps[1],
  456. }
  457. winBackRepRegexps = append(winBackRepRegexps, reg)
  458. }
  459. }
  460. BackRepRegexp["buyer"] = winBackRepRegexps
  461. var winBlackRegexps []*regexp.Regexp
  462. for _, v := range backBlack {
  463. reg := regexp.MustCompile(v.(string))
  464. winBlackRegexps = append(winBlackRegexps, reg)
  465. }
  466. BlackRegexp["buyer"] = winBlackRegexps
  467. }
  468. func initAgencyRegexp() {
  469. buyRegMap := Sysconfig["agency"].(map[string]interface{})
  470. preRegexps := buyRegMap["pre_regexp"].([]interface{})
  471. backRegexps := buyRegMap["back_regexp"].([]interface{})
  472. backRepRegexps := buyRegMap["back_rep_regexp"].([]interface{})
  473. backBlack := buyRegMap["blacklist"].([]interface{})
  474. var winPreRegexps []*regexp.Regexp
  475. for _, v := range preRegexps {
  476. reg := regexp.MustCompile("^" + v.(string))
  477. winPreRegexps = append(winPreRegexps, reg)
  478. }
  479. PreRegexp["agency"] = winPreRegexps
  480. var winBackRegexps []*regexp.Regexp
  481. for _, v := range backRegexps {
  482. reg := regexp.MustCompile(v.(string))
  483. winBackRegexps = append(winBackRegexps, reg)
  484. }
  485. BackRegexp["agency"] = winBackRegexps
  486. var winBackRepRegexps []RegexpInfo
  487. for _, v := range backRepRegexps {
  488. reps := strings.Split(v.(string), "#")
  489. if len(reps) > 1 {
  490. reg := RegexpInfo{
  491. regs: regexp.MustCompile(reps[0]),
  492. repstr: reps[1],
  493. }
  494. winBackRepRegexps = append(winBackRepRegexps, reg)
  495. }
  496. }
  497. BackRepRegexp["agency"] = winBackRepRegexps
  498. var winBlackRegexps []*regexp.Regexp
  499. for _, v := range backBlack {
  500. reg := regexp.MustCompile(v.(string))
  501. winBlackRegexps = append(winBlackRegexps, reg)
  502. }
  503. BlackRegexp["agency"] = winBlackRegexps
  504. }