package util import ( "fmt" "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXBase/rpc/bxbase" IC "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXBase/rpc/init" "log" "strconv" "strings" "time" "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/encrypt" elastic "app.yhyue.com/moapp/jybase/es" "app.yhyue.com/moapp/jybase/mongodb" "app.yhyue.com/moapp/jybase/mysql" "app.yhyue.com/moapp/jybase/redis" "go.mongodb.org/mongo-driver/bson/primitive" ) const ( query = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","subtype","s_winner","buyertel","winnertel","buyerclass"],"from":0,"size":%d}` mongodb_fields = `{"_id":1,"area":1,"publishtime":1,"s_subscopeclass":1,"subtype":1,"title":1,"toptype":1,"type":1, "buyerclass":1,"budget":1,"bidamount":1,"winnertel":1,"s_winner":1,"buyertel":1,"attach_text":1}` querys = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","title","detail","area","city","publishtime","projectname","buyer","buyerclass","s_winner","bidamount","subtype","toptype","projectcode","buyertel","budget","bidopentime","agency","projectscope","winnerperson","winnertel"],"from":0,"size":%d}}` SearchGroupBidding = 1 // 搜索分组:1:招标采购公告;2:超前项目 SearchGroupLeadingProject = 2 // 搜索分组:1:招标采购公告;2:超前项目 SearchGroupAnnouncementProject = 3 // 搜索分组:招标公告 SearchGroupForetellProject = 4 // 搜索分组:招标预告 SearchGroupResultProject = 5 // 搜索分组:招标结果 TopTypesBidding = "招标预告,招标公告,招标结果,招标信用信息" TopTypesLeadingProject = "拟建,采购意向" ) // 是否是付费用户 -bool: true:是 fasle:不是 func Power(userid string) (bool, map[string]interface{}) { isVip, isMember, isEnt := false, false, false vipstatus := 0 phone := "" var registedate int64 data := IC.Compatible.Select(userid, `"i_member_status":1,"i_vip_status":1,"s_m_phone":1,"s_phone":1,"o_vipjy":1,"l_registedate":1`) if data != nil && len(*data) > 0 { i_vip_status := common.IntAll((*data)["i_vip_status"]) if i_vip_status > 1 { vipstatus = 1 isVip = true } ovipjy, _ := (*data)["o_vipjy"].(map[string]interface{}) if ovipjy["o_buyset"] != nil { o_buyset := ovipjy["o_buyset"].(map[string]interface{}) if o_buyset["upgrade"] != nil && isVip { vipstatus = 2 } } if i_member_status := common.IntAllDef((*data)["i_member_status"], 0); i_member_status > 0 { isMember = true } if s_phone, _ := (*data)["s_phone"].(string); s_phone != "" { phone = s_phone } else if s_m_phone, _ := (*data)["s_m_phone"].(string); s_m_phone != "" { phone = s_m_phone } if phone != "" { //已购买企业未过期 if entInfo := *IC.MainMysql.SelectBySql(`SELECT status FROM entniche_info WHERE id IN (SELECT ent_id FROM entniche_user where phone = ? and power =1)`, phone); len(entInfo) > 0 { for _, v := range entInfo { if common.IntAll(v["status"]) == 1 { isEnt = true break } } } } registedate, _ = (*data)["l_registedate"].(int64) } return isVip || isEnt || isMember, map[string]interface{}{ "vip": vipstatus, "member": isMember, "entniche": isEnt, "registedate": registedate, } } // 招标信息是否被收藏 func IsCollByBids(bids, userid string) []string { res := []string{} collBidMap := map[string]bool{} isCollkey := fmt.Sprintf("isColl_%s", userid) collStatus := redis.GetInt("other", isCollkey) if collStatus == 0 { if count := int(IC.MainMysql.CountBySql(fmt.Sprintf(`select count(1) from %s where userid = ?`, "bdcollection"), userid)); count > 100 { collStatus = 2 } else if count == 0 { collStatus = 0 } else { collStatus = 1 } redis.Put("other", isCollkey, collStatus, 259200) } if collStatus == 1 { //100条内 取redis list := GetCollRedis(userid, collStatus) for _, v := range list { collBidMap[v] = true } } else if collStatus == 2 { //大于100条 取mysql if labArr := *IC.MainMysql.SelectBySql(fmt.Sprintf("select bid from %s where userid = ?", "bdcollection"), userid); len(labArr) > 0 { for _, v := range labArr { bid_id := common.ObjToString(v["bid"]) collBidMap[bid_id] = true } } } else { //0条 return res } if bids == "" { for k, _ := range collBidMap { res = append(res, k) } } else { for _, v := range strings.Split(bids, ",") { //招标信息解密 bid := DecodeId(v) if collBidMap[bid] { // url.QueryEscape(v) res = append(res, v) } } } return res } /* isColl int: 收藏条数的状态 (是否超过100条 超过:2 没超过:1) return []string:收藏的id */ func GetCollRedis(userid string, isColl int) []string { redisCollKey := fmt.Sprintf("coll_%s", userid) //列表 redisArr := []string{} if isColl == 1 { redisArr, _ = redis.Get("other", redisCollKey).([]string) if len(redisArr) == 0 { data := IC.MainMysql.SelectBySql(fmt.Sprintf(`select bid from %s where userid ='%s'`, "bdcollection", userid)) if data != nil && len(*data) > 0 { for _, v := range *data { redisArr = append(redisArr, common.ObjToString(v["bid"])) } redis.Put("other", redisCollKey, redisArr, 259200) } } } return redisArr } // 招标信息 bid&userid 唯一 type BidInfo struct { Bid string `json:"bid"` //招标信息id 加密后 Buyerclass string `json:"buyerclass"` //采购单位类型 Buyerinfo bool `json:"buyerinfo"` //是否有采购单位联系方式 Winnerinfo bool `json:"winnerinfo"` //是否有中标企业联系方式 Userid string `json:"userid"` //用户id Createdate string `json:"createdate"` //收藏时间 Labelid string `json:"labelid"` //标签ids } func FormatColl(bidinfo []string) []BidInfo { es_ids := []string{} infos := map[string]interface{}{} for _, v := range bidinfo { es_ids = append(es_ids, DecodeId(v)) } if len(es_ids) > 0 { list := elastic.Get("bidding", "bidding", fmt.Sprintf(query, strings.Join(es_ids, `","`), len(es_ids))) if list != nil { for _, v := range *list { _id := common.ObjToString(v["_id"]) //中标电话 需要查企业库 和三级页保持一致 winnertel := common.ObjToString(v["winnertel"]) if winnertel == "" && isbid(v["subtype"]) { v["winnertel"] = getwinnertel(v["s_winner"]) } infos[_id] = v } } } var bids []BidInfo if len(infos) > 0 { for _, v := range bidinfo { var bid BidInfo id := DecodeId(v) bid.Bid = v if infos[id] != nil { infoMap, _ := (infos[id]).(map[string]interface{}) if common.ObjToString(infoMap["winnertel"]) != "" { bid.Winnerinfo = true } if common.ObjToString(infoMap["buyertel"]) != "" { bid.Buyerinfo = true } if common.ObjToString(infoMap["buyerclass"]) != "" { bid.Buyerclass = common.ObjToString(infoMap["buyerclass"]) } } bids = append(bids, bid) } } return bids } func isbid(typ interface{}) bool { if typ != nil { subtype := common.ObjToString(typ) if subtype == "中标" || subtype == "合同" || subtype == "成交" { return true } } return false } func getwinnertel(company interface{}) string { if company != nil { data, _ := IC.MgoEnt.FindOneByField("winner_enterprise", map[string]interface{}{ "company_name": common.ObjToString(company), }, map[string]interface{}{"company_phone": 1}) if (*data)["company_phone"] != nil { return common.ObjToString((*data)["company_phone"]) } } return "" } //修改redis中的收藏条数; /* typ:"d"删除 typ:"a"添加 list:需要添加或删除的bid_id */ func UpdateCollListRedis(typ, userid string, list []string) bool { bl := false if len(list) == 0 { return true } Blist := []string{} m := map[string]bool{} redisCollKey := fmt.Sprintf("coll_%s", userid) collTime := 3600 * 2 if 7200 > 0 { collTime = 7200 } redisIsCollKey := fmt.Sprintf("isColl_%s", userid) //是否超过100条 超过:2 没超过:1 isCollTime := 3600 * 24 * 3 if 259200 > 0 { isCollTime = 259200 } collStatus := redis.GetInt("other", redisIsCollKey) redisArr := GetCollRedis(userid, collStatus) if len(redisArr) > 0 { for _, v := range redisArr { m[v] = true } } if typ == "a" { for _, v := range list { if m[v] { continue //去重 } Blist = append(Blist, v) } } else if typ == "d" { for _, v := range list { delete(m, v) } if len(m) > 0 { for k, _ := range m { Blist = append(Blist, k) } } } arr := append(redisArr, Blist...) status := 1 if len(arr) > 100 { status = 2 arr = []string{} } else if len(arr) == 0 { status = 0 } bl = redis.Put("other", redisCollKey, arr, collTime) && redis.Put("other", redisIsCollKey, status, isCollTime) return bl } var PushMapping = &pushMapping{} type pushMapping struct { Area map[string]int City map[string]int Toptype map[string]int Subtype map[string]int Buyerclass map[string]int Subscopeclass map[string]int } func (p *pushMapping) Init(MainMysql *mysql.Mysql) { infotype := MainMysql.SelectBySql("select id,type,name from infotype") p.Toptype = map[string]int{} p.Subtype = map[string]int{} p.Buyerclass = map[string]int{} p.Subscopeclass = map[string]int{} for _, v := range *infotype { id := common.IntAll(v["id"]) tp := common.IntAll(v["type"]) name := common.ObjToString(v["name"]) if tp == 1 { p.Toptype[name] = id } else if tp == 2 { p.Subtype[name] = id } else if tp == 3 { p.Buyerclass[name] = id } else if tp == 4 { p.Subscopeclass[name] = id } } if len(p.Toptype) == 0 { log.Fatalln("PushMapping Toptype Init Error") } if len(p.Subtype) == 0 { log.Fatalln("PushMapping Subtype Init Error") } if len(p.Buyerclass) == 0 { log.Fatalln("PushMapping Buyerclass Init Error") } if len(p.Subscopeclass) == 0 { log.Fatalln("PushMapping Subscopeclass Init Error") } // p.Area = map[string]int{} p.City = map[string]int{} province := MainMysql.SelectBySql("select id,level,name from province") for _, v := range *province { id := common.IntAll(v["id"]) level := common.IntAll(v["level"]) name := common.ObjToString(v["name"]) if level == 1 { p.Area[name] = id } else if level == 2 { p.City[name] = id } } if len(p.Area) == 0 { log.Fatalln("PushMapping Area Init Error") } if len(p.City) == 0 { log.Fatalln("PushMapping City Init Error") } } type InfoList struct { Id string `json:"_id"` Title string `json:"title"` Area string `json:"area"` Buyerclass string `json:"buyerclass"` Type string `json:"type"` S_subscopeclass string `json:"s_subscopeclass"` Publishtime int64 `json:"publishtime"` Budget interface{} `json:"budget"` Bidamount interface{} `json:"bidamount"` Buyer string `json:"buyer"` S_winner string `json:"s_winner"` Bidopentime int64 `json:"bidopentime"` FileExists bool `json:"fileExists"` } // 根据id取内容 func GetInfoById(Mgo_bidding mongodb.MongodbSim, bidding, bidding_back string, idlist []map[string]interface{}) []*InfoList { array := make([]*InfoList, len(idlist)) if len(idlist) == 0 { return array } m := map[string]bool{} ids := []string{} for _, v := range idlist { if m[common.ObjToString(v["bid"])] { continue } m[common.ObjToString(v["bid"])] = true ids = append(ids, common.ObjToString(v["bid"])) } infos := map[string]map[string]interface{}{} //redis es_ids := []string{} for _, v := range ids { info_i := redis.Get("pushcache_1", fmt.Sprintf("info_%s", v)) if info_i != nil { info_m, _ := info_i.(map[string]interface{}) info_m["_id"] = v infos[v] = info_m } else { es_ids = append(es_ids, v) } } // log.Println(es_ids) //elasticsearch if len(es_ids) > 0 { list := elastic.Get("bidding", "bidding", fmt.Sprintf(querys, strings.Join(es_ids, `","`), len(es_ids))) if list != nil { for _, v := range *list { _id := common.ObjToString(v["_id"]) v["attachment_count"] = common.If(v["filetext"] != nil, 1, 0).(int) infos[_id] = v } } } //mongodb bidding mgo_ids := []primitive.ObjectID{} for _, v := range es_ids { if infos[v] == nil { _id, _ := primitive.ObjectIDFromHex(v) mgo_ids = append(mgo_ids, _id) } } if len(mgo_ids) > 0 { list, ok := Mgo_bidding.Find(bidding, map[string]interface{}{"_id": map[string]interface{}{"$in": mgo_ids}}, nil, mongodb_fields, false, -1, -1) if ok && *list != nil { for _, v := range *list { _id := mongodb.BsonIdToSId(v["_id"]) v["_id"] = _id v["attachment_count"] = common.If(v["attach_text"] != nil, 1, 0).(int) infos[_id] = v } } } //mongodb bidding_back mgo_back_ids := []primitive.ObjectID{} for _, v := range mgo_ids { if infos[mongodb.BsonIdToSId(v)] == nil { mgo_back_ids = append(mgo_back_ids, v) } } if len(mgo_back_ids) > 0 { list, ok := Mgo_bidding.Find(bidding_back, map[string]interface{}{"_id": map[string]interface{}{"$in": mgo_back_ids}}, nil, mongodb_fields, false, -1, -1) if ok && *list != nil { for _, v := range *list { _id := mongodb.BsonIdToSId(v["_id"]) v["_id"] = _id v["attachment_count"] = common.If(v["attach_text"] != nil, 1, 0).(int) infos[_id] = v } } } // for k, v := range idlist { info := infos[common.ObjToString(v["bid"])] if info == nil { info = map[string]interface{}{} } array[k] = InfoFormat(common.ObjToString(v["bid"]), &info) } return array } // 列表单条信息格式化 func InfoFormat(p string, info *map[string]interface{}) *InfoList { area := common.ObjToString((*info)["area"]) if area == "A" { area = "全国" } industry := common.ObjToString((*info)["s_subscopeclass"]) scs := strings.Split(industry, ",") if len(scs) > 0 { industry = scs[0] if industry != "" { iss := strings.Split(industry, "_") if len(iss) > 0 { industry = iss[0] } } } infotype := common.ObjToString((*info)["subtype"]) if infotype == "" { infotype = common.ObjToString((*info)["toptype"]) } if infotype == "" { infotype = common.ObjToString((*info)["type"]) if infotype == "tender" { infotype = "招标" } else if infotype == "bid" { infotype = "中标" } } _id := p if _id == "" { _id = common.ObjToString((*info)["_id"]) } return &InfoList{ Id: encrypt.EncodeArticleId2ByCheck(_id), Title: common.ObjToString((*info)["title"]), Area: area, Buyerclass: common.ObjToString((*info)["buyerclass"]), Type: infotype, S_subscopeclass: industry, Publishtime: common.Int64All((*info)["publishtime"]), Budget: (*info)["budget"], Bidamount: (*info)["bidamount"], Buyer: common.ObjToString((*info)["buyer"]), S_winner: common.ObjToString((*info)["s_winner"]), Bidopentime: common.Int64All((*info)["bidopentime"]), FileExists: common.IntAll((*info)["attachment_count"]) > 0, } } // 搜藏列表 func CollListSql(c *bxbase.ListReq, isPay bool, userid string) string { sql := fmt.Sprintf(`select bid from %s where userid ='%s'`, "bdcollection", userid) limit := 10 //个人标签 if c.Label != "" { i := 0 sql += ` and ` if labelArr := strings.Split(c.Label, ","); len(labelArr) > 0 { sql += `(` for _, v := range labelArr { i++ labid := encrypt.SE.DecodeString(v) if i == len(labelArr) { sql += fmt.Sprintf(`FIND_IN_SET(%s,labelid)`, labid) } else { sql += fmt.Sprintf(`FIND_IN_SET(%s,labelid) or `, labid) } } sql += `)` } } now := time.Now() start, end := "", "" //收藏时间 if c.SelectTime == "lately-7" { //最近7天 start = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-7, 0, 0, 0, 0, time.Local).Format(Date_Full_Layout)) } else if c.SelectTime == "lately-30" { //最近30天 start = fmt.Sprint(time.Date(now.Year(), now.Month(), now.Day()-30, 0, 0, 0, 0, time.Local).Format(Date_Full_Layout)) } else if c.SelectTime == "thisyear" { //去年 start = fmt.Sprint(time.Date(now.Year()-1, 1, 1, 0, 0, 0, 0, time.Local).Format(Date_Full_Layout)) end = fmt.Sprint(time.Date(now.Year()-1, 12, 31, 23, 59, 59, 0, time.Local).Format(Date_Full_Layout)) } else if len(strings.Split(c.SelectTime, "_")) == 2 { if c.SelectTime != "0_0" { starttime := strings.Split(c.SelectTime, "_")[0] startstamp, _ := strconv.Atoi(starttime) start = time.Unix(int64(startstamp), 0).Format(Date_Full_Layout) endtime := strings.Split(c.SelectTime, "_")[1] et, _ := strconv.ParseInt(endtime, 0, 64) etTime := time.Unix(et, 0) end = fmt.Sprint(time.Date(etTime.Year(), etTime.Month(), etTime.Day()+1, 0, 0, 0, 0, time.Local).Format(Date_Full_Layout)) } } if start != "" && end != "" { sql += ` and createdate >= '` + start + `' and createdate < '` + end + `'` } else if start != "" && end == "" { sql += ` and createdate >= '` + start + `'` } else if start == "" && end != "" { sql += ` and createdate < '` + end + `'` } if isPay { //采购单位 用,分隔开 if c.Buyerclass != "" { i := 0 sql += ` and buyerclass in (` if buyClassArr := strings.Split(c.Buyerclass, ","); len(buyClassArr) > 0 { for _, v := range buyClassArr { i++ buyerclassid := fmt.Sprint(PushMapping.Buyerclass[v]) if i == len(buyClassArr) { sql += buyerclassid + `)` } else { sql += buyerclassid + "," } } } } //是否存在采购单位电话 if c.BuyerPhone == 1 { sql += ` and buyerinfo = 1` } else if c.BuyerPhone == -1 { sql += ` and buyerinfo = 0` } //是否存在中标单位电话 if c.WinnerPhone == 1 { sql += ` and winnerinfo = 1` } else if c.WinnerPhone == -1 { sql += ` and winnerinfo = 0` } limit = 5000 } sql += fmt.Sprintf(` order by createdate desc limit %v`, limit) return sql }