123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- package main
- import (
- "qfw/util"
- "qfw/util/redis"
- "regexp"
- "sort"
- "strings"
- "time"
- "gopkg.in/mgo.v2/bson"
- )
- /**
- 发布时间(结合信息类型-->)
- 信息类型(拟建、招标(变更)、结果(成交、中标、流标、废标、变更)、其他(合同、验收、违规、变更))
- 项目代码(长度)
- 采购单位(结合省份)
- 招标机构
- 所属省份
- 信息标题(含有二次、标段、包的情况,结合分包情况处理)
- 是否分包:
- **/
- type ProjectInfo struct {
- Id string `json:"id"`
- Publistime []int64 `json:"publistime"` //多条信息的发布时间、跨度
- InfoType [][]string `json:"infotype"` //多条信息内的 toptype、subtype
- Ids []string `json:"ids"`
- Topscopeclass []string `json:"topscopeclass"`
- Subscopeclass []string `json:"subscopeclass"`
- Winners []string `json:"winners"`
- ProjectName string `json:"projectname"`
- ProjectCode string `json:"projectcode"` //项目代码唯一(纯数字的权重低)
- Buyer string `json:"buyer"` //采购单位唯一
- Buyerperson string `json:"buyerperson"`
- Buyertel string `json:"buyertel"`
- Agency string `json:"agency"` //代理机构唯一
- Area string `json:"area"` //地区唯一
- City string `json:"city"` //地市
- HasPackage bool `json:"haspackage"` //是否有分包
- Package map[string]interface{} `json:"package"` //分包的对比对象
- Buyerclass string `json:"buyerclass"` //采购单位分类
- Bidopentime int64 `json:"bidopentime"` //开标时间
- District string `json:"district"` //区县
- Winnerorder []string //中标候选人
- }
- type CompareOne struct {
- ProjectNameType string //项目名称对比结果分类 A相等 B包含 C不相等 Dthis存在对比不存在 Ethis不存在
- ProjectCodeType string //同上
- BuyerType string //同上
- AreaType string //同上
- AgencyType string //同上
- PublistimeType int //1在时间范围 2不在
- PackageType int //1都是多包 2都不是多包 3招标 4新信息是结果
- Score int
- Parent *CompareInfo
- Pinfo *ProjectInfo
- Pos int
- Cresult string //对比结果
- }
- type CompareInfo struct {
- Field string //对比属性 pn/pc/pb
- Key string //存放rediskey
- Scores []*CompareOne //对比分值 pinfo索引对应分值
- Bfind bool //是否查找到
- IdArr []string
- K *Key
- KeyMap *KeyMap
- }
- func NewCompareInfo(field, key string, KeyMap *KeyMap) *CompareInfo {
- return &CompareInfo{
- Field: field,
- Key: key,
- Scores: []*CompareOne{},
- KeyMap: KeyMap,
- }
- }
- var numreg2 = regexp.MustCompile("^[0-9]+$")
- var TitleReg = regexp.MustCompile("([一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ、\\-~至]+(子|合同|分|施工|监理|标)?[包标段][号段]?[、]?)+|((子|合同|分|施工|监理|标)?[包标段][号段]?[一二三四五六七八九十0-9A-Za-zⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ、\\-~至]+[、]?)+|(子|合同|分|施工|监理|标)?[包标段][号段]?[a-zA-Z0-9]+[\\-~-至、](子|合同|分|施工|监理|标)?[包标段][号段]?[a-zA-Z0-9]+")
- //没有在redis中查找到,新增项目
- func InsertProject(new_pn string, tmp, mess map[string]interface{}, pici int64, thisinfo *Info) string {
- e := InitEL("")
- set := map[string]interface{}{
- "pici": pici,
- }
- set["s_projectname"] = new_pn
- e.fieldpriority(&tmp, nil, &set)
- set["extractpos"] = e.GetVal()
- set["createtime"] = time.Now().Unix()
- set["sourceinfoid"] = util.BsonIdToSId(tmp["_id"])
- set["sourceinfourl"] = tmp["href"]
- set["topscopeclass"] = thisinfo.Topscopeclass
- set["subscopeclass"] = thisinfo.Subscopeclass
- if thisinfo.Buyerperson != "" {
- set["buyerperson"] = thisinfo.Buyerperson
- }
- if thisinfo.Buyertel != "" {
- set["buyertel"] = thisinfo.Buyertel
- }
- if thisinfo.Buyerclass != "" {
- set["buyertel"] = thisinfo.Buyerclass
- }
- if thisinfo.District != "" {
- set["district"] = thisinfo.District
- }
- if thisinfo.Bidopentime > 0 {
- set["bidopentime"] = thisinfo.Bidopentime
- }
- if len(thisinfo.Winnerorder) > 0 {
- set["winnerorder"] = thisinfo.Winnerorder
- }
- s_subscopeclass := strings.Join(thisinfo.Subscopeclass, ",")
- set["s_subscopeclass"] = s_subscopeclass
- s_winner := strings.Join(thisinfo.Winners, ",")
- set["s_winner"] = s_winner
- if tmp["package"] != nil {
- set["package"] = tmp["package"] //没定义优先级
- }
- push := NewPushInfo(tmp)
- for tkey, _ := range extractpos {
- if tmp[tkey] != nil {
- push[tkey] = tmp[tkey]
- }
- }
- set["list"] = []bson.M{
- push,
- }
- if mess != nil { //项目标识
- for k, v := range mess {
- set[k] = v
- }
- }
- return MQFW.Save(projectColl, set)
- }
- //生成存放在redis数组中的对象
- func NewPinfo(id string, thisinfo *Info) ProjectInfo {
- p1 := ProjectInfo{
- Publistime: []int64{thisinfo.Publishtime},
- InfoType: [][]string{[]string{thisinfo.TopType, thisinfo.SubType}},
- Id: id,
- Ids: []string{thisinfo.Id},
- Topscopeclass: thisinfo.Topscopeclass,
- Subscopeclass: thisinfo.Subscopeclass,
- Winners: thisinfo.Winners,
- ProjectName: thisinfo.ProjectName,
- ProjectCode: thisinfo.ProjectCode,
- Buyer: thisinfo.Buyer,
- Agency: thisinfo.Agency,
- Area: thisinfo.Area,
- HasPackage: thisinfo.HasPackage,
- Package: map[string]interface{}{},
- Buyerclass: thisinfo.Buyerclass,
- Bidopentime: thisinfo.Bidopentime,
- District: thisinfo.District,
- Winnerorder: thisinfo.Winnerorder,
- }
- for k4, _ := range thisinfo.Package {
- p1.Package[k4] = ""
- }
- return p1
- }
- //每一个字段的打分map,获取最高分
- func GetMaxScore(scoremap map[int]int) (find bool, index int) {
- ks := []int{}
- vs := []int{}
- for k, v := range scoremap {
- mk, mv := -1, -100
- bf := false
- for mk, mv = range vs {
- if mv > v {
- bf = true
- break
- }
- }
- if mk == -1 || !bf {
- vs = append(vs, v)
- ks = append(ks, k)
- } else {
- vs = append(append(vs[:mk], v), vs[mk:]...)
- ks = append(append(ks[:mk], k), ks[mk:]...)
- }
- }
- if len(ks) > 0 {
- index = ks[len(ks)-1]
- find = true
- }
- return
- }
- //往对应redis中更新信息
- func updateinfo(thisinfo *Info, tmp map[string]interface{}, pInfo *ProjectInfo, pici int64) string {
- updateid := pInfo.Id
- if BinarySearch(pInfo.Ids, thisinfo.Id) > -1 {
- return updateid
- }
- set := map[string]interface{}{
- "pici": pici,
- }
- res, bres := MQFW.FindById(projectColl, pInfo.Id, `{"list":0}`)
- EqInfoUpdate(thisinfo, pInfo)
- if bres && res != nil && *res != nil {
- set["topscopeclass"] = pInfo.Topscopeclass
- set["subscopeclass"] = pInfo.Subscopeclass
- s_subscopeclass := strings.Join(pInfo.Subscopeclass, ",")
- if len(s_subscopeclass) > 0 {
- s_subscopeclass = "," + s_subscopeclass + ","
- }
- set["s_subscopeclass"] = s_subscopeclass
- s_winner := strings.Join(pInfo.Winners, ",")
- if len(s_winner) > 0 {
- s_winner = "," + s_winner + ","
- }
- set["s_winner"] = s_winner
- if pInfo.Buyerperson != "" && pInfo.Buyertel != "" {
- set["buyerperson"] = pInfo.Buyerperson
- set["buyertel"] = pInfo.Buyertel
- }
- if pInfo.Buyerclass != "" {
- set["buyerclass"] = pInfo.Buyerclass
- }
- if pInfo.District != "" {
- set["district"] = pInfo.District
- }
- if pInfo.Bidopentime > 0 {
- set["bidopentime"] = pInfo.Bidopentime
- }
- if len(pInfo.Winnerorder) > 0 {
- set["winnerorder"] = pInfo.Winnerorder
- }
- if thisinfo.HasPackage {
- set["multipackage"] = 1
- } else {
- set["multipackage"] = 0
- }
- e := InitEL(util.ObjToString((*res)["extractpos"]))
- if thisinfo.dealtype == 1 {
- var sonpackage map[string]interface{}
- for _, obj := range tmp["package"].(map[string]interface{}) {
- sonpackage, _ = obj.(map[string]interface{})
- }
- for _, v2 := range []string{"budget", "budget_w", "winner", "winner_w", "bidstatus", "bidstatus_w"} {
- if sonpackage[v2] != nil {
- tmp[v2] = sonpackage[v2]
- }
- }
- }
- e.fieldpriority(&tmp, res, &set)
- set["extractpos"] = e.GetVal()
- if thisinfo.HasPackage { //多包处理
- p1, _ := (*res)["package"].(map[string]interface{})
- p2, _ := tmp["package"].(map[string]interface{})
- if p2 != nil {
- if p1 != nil {
- for pk2, pv2 := range p2 {
- if p1[pk2] != nil { //合并
- item1, _ := p1[pk2].(map[string]interface{})
- item2, _ := pv2.(map[string]interface{})
- if item1 != nil && item2 != nil { //原始项
- for ik1, iv1 := range item2 {
- if item1[ik1] == nil {
- item1[ik1] = iv1
- }
- }
- }
- } else {
- p1[pk2] = pv2
- }
- }
- } else {
- p1 = p2
- }
- }
- set["package"] = p1
- }
- //中标候选人合并
- update := map[string]interface{}{}
- if len(set) > 0 {
- update["$set"] = set
- }
- //保留原数据吧
- push := NewPushInfo(tmp)
- for tkey, _ := range extractpos {
- if tmp[tkey] != nil {
- push[tkey] = tmp[tkey]
- }
- }
- update["$push"] = map[string]interface{}{
- "list": push,
- }
- if len(update) > 0 {
- MQFW.Update(projectColl, map[string]interface{}{
- "_id": util.StringTOBsonId(pInfo.Id),
- }, &update, false, false)
- }
- }
- //再往redis中放 index
- //往队列中增加时间 -------------->start
- redis.Put(REDISIDS, updateid, pInfo, 0)
- return updateid
- }
- func EqInfoUpdate(thisinfo *Info, pInfo *ProjectInfo) {
- var tk int
- bf1 := false
- for _k, tv := range pInfo.Publistime {
- tk = _k
- if tv > thisinfo.Publishtime {
- bf1 = true
- break
- }
- }
- if bf1 {
- pInfo.Publistime = append(append(pInfo.Publistime[:tk], thisinfo.Publishtime), pInfo.Publistime[tk:]...)
- pInfo.InfoType = append(append(pInfo.InfoType[:tk], []string{thisinfo.TopType, thisinfo.SubType}), pInfo.InfoType[tk:]...)
- pInfo.Ids = append(append(pInfo.Ids[:tk], thisinfo.Id), pInfo.Ids[tk:]...)
- } else {
- pInfo.Publistime = append(pInfo.Publistime, thisinfo.Publishtime)
- pInfo.InfoType = append(pInfo.InfoType, []string{thisinfo.TopType, thisinfo.SubType})
- pInfo.Ids = append(pInfo.Ids, thisinfo.Id)
- }
- //增加发布时间结束----------------->end
- if (pInfo.Buyer == "" && thisinfo.Buyer != "") || (len([]rune(pInfo.Buyer)) < 5 && len([]rune(thisinfo.Buyer)) > 5) {
- pInfo.Buyer = thisinfo.Buyer
- }
- if (pInfo.Agency == "" && thisinfo.Agency != "") || (len([]rune(pInfo.Agency)) < 5 && len([]rune(thisinfo.Agency)) > 5) {
- pInfo.Agency = thisinfo.Agency
- }
- if (pInfo.ProjectCode == "" && thisinfo.ProjectCode != "") || (len([]rune(pInfo.ProjectCode)) < 6 && len([]rune(thisinfo.ProjectCode)) > 6) {
- pInfo.ProjectCode = thisinfo.ProjectCode
- }
- if thisinfo.Buyerperson != "" && thisinfo.Buyertel != "" && len([]rune(thisinfo.Buyertel)) > 6 {
- pInfo.Buyerperson = thisinfo.Buyerperson
- pInfo.Buyertel = thisinfo.Buyertel
- }
- if thisinfo.Buyerclass != "" {
- pInfo.Buyerclass = thisinfo.Buyerclass
- }
- if thisinfo.District != "" {
- pInfo.District = thisinfo.District
- }
- if thisinfo.Bidopentime > 0 {
- pInfo.Bidopentime = thisinfo.Bidopentime
- }
- 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)
- }
- }
- }
- 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)
- }
- }
- }
- //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)
- }
- }
- }
- //winnerorder
- if len(thisinfo.Winnerorder) > 0 {
- sort.Strings(pInfo.Winnerorder)
- for _, k := range thisinfo.Winnerorder {
- if BinarySearch(pInfo.Winnerorder, k) == -1 {
- pInfo.Winnerorder = append(pInfo.Winnerorder, k)
- sort.Strings(pInfo.Winnerorder)
- }
- }
- }
- //return pInfo
- }
- //二分字符串查找
- func BinarySearch(s []string, k string) int {
- sort.Strings(s)
- lo, hi := 0, len(s)-1
- for lo <= hi {
- m := (lo + hi) >> 1
- if s[m] < k {
- lo = m + 1
- } else if s[m] > k {
- hi = m - 1
- } else {
- return m
- }
- }
- return -1
- }
- //移除数组中重复的元素
- func RemoveDup(arr []string) (newarr []string) {
- m1 := map[string]bool{}
- newarr = []string{}
- for _, k := range arr {
- if !m1[k] {
- m1[k] = true
- newarr = append(newarr, k)
- }
- }
- return
- }
|