123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791 |
- package model
- import (
- "app.yhyue.com/moapp/jybase/redis"
- "encoding/json"
- "fmt"
- IC "jyBXBuyer/rpc/init"
- "jyBXBuyer/rpc/type/bxbuyer"
- "log"
- "strconv"
- "strings"
- "sync"
- "time"
- MC "app.yhyue.com/moapp/jybase/common"
- "app.yhyue.com/moapp/jybase/encrypt"
- elastic "app.yhyue.com/moapp/jybase/es"
- "github.com/zeromicro/go-zero/core/logx"
- )
- const (
- HasContact = 1 // 采购单位是否有联系方式筛选项 1-有联系方式
- NoContact = 2 // 无联系方式
- )
- type BScope struct {
- Keyword []string `json:"keyword"`
- AdditionalWords []string `json:"additionalWords"`
- ExcludedWords []string `json:"excludedWords"`
- }
- type supplyDataStruct struct {
- ProjectCount int64
- BidCount int64
- BidAmountCount float32
- ContactCount int64
- }
- // 获取采购单位查询query
- func BuyerListQuery(in *bxbuyer.BuyerListReq) (qstr string, CountQstr string) {
- query := `{%s "query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer_name": ""}}],"should":[%s],"minimum_should_match": %d}} %s}`
- //21.1.20 为和画像保持一致 数据组要求 budget 改成 bidamount
- query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
- sort := ""
- bools := []string{}
- musts := []string{}
- musts_should := []string{}
- //省份
- if len(in.Province) > 0 {
- musts_should = append(musts_should, fmt.Sprintf(`{"terms":{"province":["%s"]}}`, strings.Join(in.Province, "\",\"")))
- }
- //城市
- if len(in.City) > 0 {
- musts_should = append(musts_should, fmt.Sprintf(`{"terms":{"city":["%s"]}}`, strings.Join(in.City, "\",\"")))
- }
- if len(musts_should) > 0 {
- musts = append(musts, fmt.Sprintf(query_bool_should, strings.Join(musts_should, ",")))
- }
- //采购单位名称
- if in.BuyerName != "" {
- entNameQuery := fmt.Sprintf(`{"multi_match": {"query": "%s","type": "phrase", "fields": ["name"]}}`, in.BuyerName)
- musts = append(musts, entNameQuery)
- } else {
- sort = `,"sort":[{"updatetime":"desc"}]` // 仅无关键词时再
- }
- //采购单位类型
- buyerclass := in.BuyerClass
- if len(buyerclass) > 0 {
- Buyerclass := `{"terms":{"buyerclass":[`
- for k, v := range buyerclass {
- if k > 0 {
- Buyerclass += `,`
- }
- Buyerclass += `"` + v + `"`
- }
- Buyerclass += `]}}`
- musts = append(musts, Buyerclass)
- }
- // 采购单位联系方式 0-不限 1-有联系人 2-无联系人
- if in.IsContact != 0 {
- isContact := MC.If(in.IsContact == int64(HasContact), true, false)
- isContactStr := `{"term":{"is_contact":` + fmt.Sprint(isContact) + `}}`
- musts = append(musts, isContactStr)
- }
- boolsNum := 0
- qstr = fmt.Sprintf(query, fmt.Sprintf(`"from":%d,"size": %d,`, (in.PageNum-1)*in.PageSize, in.PageSize), strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, sort)
- CountQstr = fmt.Sprintf(query, "", strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, "")
- return
- }
- // 采购单位补充采购规模、项目数量、招标动态数量
- func SupplyDataQuery(buyerList []string) (query string) {
- // 查近两年的数据 因为bigmember BuyerMiniPortrait 查的默认是两年
- q := `{"size":0,"query": { "bool": { "must": [ {"terms": { "buyer": ["` + strings.Join(buyerList, "\",\"") + `"] }},{"range": {"jgtime": {"gte": %d,"lt": %d} }} ]}}, "aggs": { "buyerBuckets": {"terms": {"field": "buyer"
- },"aggs": {"bidAmountCount": {"sum": {"field": "bidamount"}}}}}}`
- start, end := getTimeRange()
- return fmt.Sprintf(q, start.Unix(), end.Unix())
- }
- func getTimeRange() (st, et time.Time) {
- now := time.Now()
- eYear := now.Year()
- sYear := now.Year() - 2
- //返回默认时间
- sTimeStamp := time.Date(sYear, 1, 1, 0, 0, 0, 0, time.Local)
- eTimeStamp := time.Date(eYear, now.Month(), now.Day(), now.Hour(), now.Minute(), 0, 0, time.Local)
- return sTimeStamp, eTimeStamp
- }
- const (
- P_INDEX = "projectset"
- P_TYPE = "projectset"
- P_redis_time = 7 * 24 * 60 * 60 //redis存7天
- P_redis_key = "buyerListCache" // 存缓存 100条数据
- BuyerIndex = "buyer" // 采购单位index
- BuyerType = "buyer"
- biddingIndex = "bidding"
- biddingType = "bidding"
- BuyerSupplyInfoRedisKey = "BuyerSupplyInfo_%s" // 采购单位补充信息缓存
- BuyerSupplyInfoRedisTime = 2 * 60 * 60 // 采购单位补充信息缓存时间 一个小时
- BuyerProjectInfoRedisKey = "BuyerProjectInfo_%s" // 采购单位补充项目信息缓存Key (项目数量采购规模)
- BuyerProjectInfoRedisTime = 24 * 60 * 60 // 采购单位补充项目信息缓存时间
- )
- // GetBuyerList 查询采购单位列表
- func GetBuyerList(qstr string, CountQuery string, isCache bool) (buyerNames []string, resp *bxbuyer.BuyerListResp) {
- t1 := time.Now()
- total := elastic.Count(BuyerIndex, BuyerType, CountQuery) // 总数
- logx.Info("耗时1:", time.Since(t1))
- resp = &bxbuyer.BuyerListResp{
- Data: &bxbuyer.BuyerData{
- Count: total,
- List: []*bxbuyer.BuyerList{},
- },
- }
- if total == 0 {
- return
- }
- start := time.Now()
- rs := elastic.Get(BuyerIndex, BuyerType, qstr) // 采购单位列表
- logx.Info("采购单位列表 es get查询耗时", time.Since(start))
- if rs == nil || len(*rs) == 0 {
- return
- }
- for i := 0; i < len(*rs); i++ {
- tmp := &bxbuyer.BuyerList{
- SeoId: MC.ObjToString((*rs)[i]["seo_id"]),
- Buyer: MC.ObjToString((*rs)[i]["name"]),
- Province: MC.ObjToString((*rs)[i]["province"]),
- City: MC.ObjToString((*rs)[i]["city"]),
- BuyerClass: MC.ObjToString((*rs)[i]["buyerclass"]),
- }
- buyerNames = append(buyerNames, tmp.Buyer)
- resp.Data.List = append(resp.Data.List, tmp)
- }
- logx.Info("耗时;", time.Since(t1).Seconds(), "秒--", time.Since(t1).Microseconds())
- return
- }
- // BuyerListRedisCache 空搜索 1.查询项目数量最多的前200个 2.然后 再查buyer里确认数据有效 100个 3.项目数量和采购规模单独存缓存 1天
- //
- // func BuyerListRedisCache(query string, in *bxbuyer.BuyerListReq) (buyerNames []string, resp *bxbuyer.BuyerListResp) {
- // //获取缓存数据
- // resp = &bxbuyer.BuyerListResp{
- // Data: &bxbuyer.BuyerData{
- // List: []*bxbuyer.BuyerList{},
- // },
- // }
- // t1 := time.Now()
- // logx.Info("耗时1:", time.Since(t1))
- // aggs := GetAggs(P_INDEX, P_TYPE, query)
- // logx.Info("查询语句:", query)
- // logx.Info("BuyerListRedisCache:", time.Since(t1))
- // type BuyerAggStruct struct {
- // Buckets []struct {
- // Key string `json:"key,omitempty"`
- // Doc_count int64 `json:"doc_count,omitempty"`
- // BidAmountCount struct {
- // Value float32 `json:"value,omitempty"`
- // } `json:"bidAmountCount"`
- // } `json:"buckets"`
- // }
- // var buyerBuckets = BuyerAggStruct{}
- // saveBuyerList := []*bxbuyer.BuyerList{} //100条数据 最后存起来
- // // 处理成map 用于后面格式化数据
- // if aggs == nil || aggs["buyerBuckets"] == nil {
- // return
- // }
- // bs, err := aggs["buyerBuckets"].MarshalJSON()
- // if err != nil {
- // resp.ErrCode = -1
- // resp.ErrMsg = "获取数据异常"
- // return
- // }
- // if len(bs) == 0 {
- // resp.ErrMsg = "暂无数据"
- // return
- // }
- // err = json.Unmarshal(bs, &buyerBuckets)
- // if err != nil || len(buyerBuckets.Buckets) == 0 {
- // resp.ErrMsg = "暂无数据"
- // return
- // }
- // for i := 0; i < len(buyerBuckets.Buckets); i++ {
- // if len(saveBuyerList) == int(IC.C.BuyerSearchLimit) {
- // break
- // }
- // // 查buyer 确认数据存在 补充 buyerclass 省份 城市信息
- // rs := GetBuyer(buyerBuckets.Buckets[i].Key)
- // if rs != nil && len(*rs) > 0 { // 存在 则追加
- // tmpBuyerInfo := (*rs)[0]
- // buyerInfo := &bxbuyer.BuyerList{
- // Buyer: buyerBuckets.Buckets[i].Key,
- // Province: MC.ObjToString(tmpBuyerInfo["province"]),
- // City: MC.ObjToString(tmpBuyerInfo["city"]),
- // BuyerClass: MC.ObjToString(tmpBuyerInfo["buyerclass"]),
- // }
- // saveBuyerList = append(saveBuyerList, buyerInfo)
- // buyerNames = append(buyerNames, buyerInfo.Buyer)
- // // 项目数量和采购规模存缓存 1天
- // projectCacheData := supplyDataStruct{
- // ProjectCount: buyerBuckets.Buckets[i].Doc_count,
- // BidAmountCount: buyerBuckets.Buckets[i].BidAmountCount.Value,
- // }
- // go func(buyer string, data supplyDataStruct) {
- // b, err := json.Marshal(data)
- // if err == nil {
- // redis.PutBytes("other", fmt.Sprintf(BuyerProjectInfoRedisKey, buyer), &b, BuyerProjectInfoRedisTime+GetRand(60))
- // }
- // }(buyerBuckets.Buckets[i].Key, projectCacheData)
- //
- // }
- // }
- // if len(saveBuyerList) > 0 {
- // // 100 列表存redis 7天
- // go func(data []*bxbuyer.BuyerList) {
- // b, err := json.Marshal(data)
- // if err == nil {
- // redis.PutBytes("other", fmt.Sprintf(P_redis_key), &b, P_redis_time)
- // }
- // }(saveBuyerList)
- // } else {
- // return
- // }
- //
- // // 根据页码返回数据
- // start := in.PageSize * (in.PageNum - 1)
- // end := in.PageSize * in.PageNum
- // resp.Data.Count = int64(len(saveBuyerList))
- // if end > int64(len(saveBuyerList)-1) {
- // end = int64(len(saveBuyerList) - 1)
- // }
- // resp.Data.List = saveBuyerList[start:end]
- // return
- // }
- func BuyerListRedisCache(query string, in *bxbuyer.BuyerListReq) (buyerNames []string, resp *bxbuyer.BuyerListResp) {
- //获取缓存数据
- resp = &bxbuyer.BuyerListResp{
- Data: &bxbuyer.BuyerData{
- List: []*bxbuyer.BuyerList{},
- },
- }
- t1 := time.Now()
- rs := elastic.Get(BuyerIndex, BuyerType, query) // 采购单位列表
- logx.Info("空搜索采购单位列表 es get查询耗时", time.Since(t1))
- if rs == nil || len(*rs) == 0 {
- return
- }
- saveBuyerList := []*bxbuyer.BuyerList{} //最后缓存起来
- for i := 0; i < len(*rs); i++ {
- tmp := &bxbuyer.BuyerList{
- SeoId: MC.ObjToString((*rs)[i]["seo_id"]),
- Buyer: MC.ObjToString((*rs)[i]["name"]),
- Province: MC.ObjToString((*rs)[i]["province"]),
- City: MC.ObjToString((*rs)[i]["city"]),
- BuyerClass: MC.ObjToString((*rs)[i]["buyerclass"]),
- }
- buyerNames = append(buyerNames, tmp.Buyer)
- saveBuyerList = append(saveBuyerList, tmp)
- }
- if len(saveBuyerList) > 0 {
- // 100 列表存redis 7天
- go func(data []*bxbuyer.BuyerList) {
- b, err := json.Marshal(data)
- if err == nil {
- redis.PutBytes("other", fmt.Sprintf(P_redis_key), &b, P_redis_time)
- }
- }(saveBuyerList)
- } else {
- return
- }
- // 根据页码返回数据
- start := in.PageSize * (in.PageNum - 1)
- end := in.PageSize * in.PageNum
- resp.Data.Count = int64(len(saveBuyerList))
- if end > int64(len(saveBuyerList)) {
- end = int64(len(saveBuyerList))
- }
- resp.Data.List = saveBuyerList[start:end]
- logx.Info("空搜索整体耗时;", time.Since(t1).Seconds(), "秒--", time.Since(t1).Microseconds())
- return
- }
- // GetBuyer 查采购单位表 确认采购单位存在
- func GetBuyer(buyerName string) *[]map[string]interface{} {
- q := `{"size":1,"_source":["buyerclass","province","city"],"query":{"bool":{"must":[{"term":{"buyer_name":"%s"}}]}}}`
- rs := elastic.Get(BuyerIndex, BuyerType, fmt.Sprintf(q, buyerName))
- return rs
- }
- // SupplyFollowInfo 补充是否关注信息
- func SupplyFollowInfo(in *bxbuyer.BuyerListReq, buyerNames []string, resp *bxbuyer.BuyerListResp) *bxbuyer.BuyerListResp {
- //省份和城市 是否查询已关注信息 是否查询已领取信息
- //企业信用库qyxy_std 和es buyer库 查询省份和城市
- //客户领取
- t2 := time.Now()
- isRws := map[string]string{}
- if in.IsCheckReceive {
- isRws = IsReceived(buyerNames, in.EntUserId)
- }
- logx.Info("客户领取耗时:", time.Since(t2))
- //客户关注
- t3 := time.Now()
- isFws := map[string]bool{}
- if in.IsCheckFollow {
- isFws = IsFollowd(buyerNames, in.UserId)
- }
- logx.Info("采购单位关注耗时:", time.Since(t3))
- for _, bv := range resp.Data.List {
- if in.IsCheckReceive {
- if isRws[bv.Buyer] != "" {
- bv.IsReceived = true
- bv.RecId = isRws[bv.Buyer]
- }
- }
- if in.IsCheckFollow {
- if isFws[bv.Buyer] {
- bv.IsFollowed = true
- }
- }
- }
- return resp
- }
- // SupplyBuyerListData 补充字段 招标动态数量 项目数量 历史联系人数量 采购单位规模
- func SupplyBuyerListData(buyerNames []string, resp *bxbuyer.BuyerListResp) *bxbuyer.BuyerListResp {
- //buyerNames 是否存在缓存 数据
- //如果没有 放到一个新的 []string
- needSearchBuyer := []string{}
- cacheMap := map[string]supplyDataStruct{}
- for i := 0; i < len(buyerNames); i++ {
- bs, err := redis.GetBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, buyerNames[i]))
- if err == nil && bs != nil && len(*bs) > 0 {
- tmp := supplyDataStruct{}
- if err := json.Unmarshal(*bs, &tmp); err == nil {
- cacheMap[buyerNames[i]] = tmp // 拿到缓存的数据
- } else {
- needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查
- }
- } else {
- needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查
- }
- }
- start := time.Now()
- t1 := time.Now()
- buyerMap := map[string]supplyDataStruct{} // 聚合的数据
- if len(needSearchBuyer) > 0 {
- query := SupplyDataQuery(needSearchBuyer) // 项目数量、采购规模
- // 聚合查
- aggs := GetAggs(P_INDEX, P_TYPE, query)
- logx.Info("查询语句:", query)
- logx.Info("项目数量采购规模查询耗时:", time.Since(t1))
- type BuyerAggStruct struct {
- Buckets []struct {
- Key string `json:"key,omitempty"`
- Doc_count int64 `json:"doc_count,omitempty"`
- BidAmountCount struct {
- Value float32 `json:"value,omitempty"`
- } `json:"bidAmountCount"`
- } `json:"buckets"`
- }
- var buyerBuckets = BuyerAggStruct{}
- // 处理成map 用于后面格式化数据
- if aggs != nil && aggs["buyerBuckets"] != nil {
- bs, err := aggs["buyerBuckets"].MarshalJSON()
- if err != nil {
- resp.ErrCode = -1
- resp.ErrMsg = "获取数据异常"
- } else {
- if len(bs) == 0 {
- resp.ErrMsg = "暂无数据"
- } else {
- err := json.Unmarshal(bs, &buyerBuckets)
- logx.Info(err)
- if len(buyerBuckets.Buckets) > 0 {
- for _, v := range buyerBuckets.Buckets {
- buyerMap[v.Key] = supplyDataStruct{
- BidAmountCount: v.BidAmountCount.Value,
- ProjectCount: v.Doc_count,
- }
- }
- }
- }
- }
- }
- }
- ch := make(chan int, 10)
- ch2 := make(chan int, 10)
- wg := &sync.WaitGroup{}
- for i := 0; i < len(resp.Data.List); i++ {
- buyer := resp.Data.List[i].Buyer
- // 先查缓存
- if cacheData, ok := cacheMap[buyer]; ok {
- resp.Data.List[i].BidAmountCount = cacheData.BidAmountCount
- resp.Data.List[i].ProjectCount = cacheData.ProjectCount
- resp.Data.List[i].BiddingCount = cacheData.BidCount
- resp.Data.List[i].ContactCount = cacheData.ContactCount
- continue
- }
- // 缓存里没有的再查数据补充
- if supplyData, ok := buyerMap[buyer]; ok {
- resp.Data.List[i].BidAmountCount = supplyData.BidAmountCount
- resp.Data.List[i].ProjectCount = supplyData.ProjectCount
- }
- ch2 <- 1
- wg.Add(1)
- go func(list *bxbuyer.BuyerList, buyer string) {
- defer func() {
- <-ch2
- wg.Done()
- }()
- list.ContactCount = GetProjectContactCount(buyer) // 补充联系人字段
- }(resp.Data.List[i], buyer)
- ch <- 1
- wg.Add(1)
- go func(list *bxbuyer.BuyerList, buyer string) {
- defer func() {
- <-ch
- wg.Done()
- }()
- list.BiddingCount = GetNewBiddingCount(buyer)
- }(resp.Data.List[i], buyer)
- }
- wg.Wait()
- logx.Info("SupplyBuyerListData 整体耗时:", time.Since(start))
- //得到所有数据,包括 redis里的,再存一下
- go func(respList []*bxbuyer.BuyerList) {
- for i := 0; i < len(respList); i++ {
- tmp := supplyDataStruct{
- ContactCount: respList[i].ContactCount,
- BidCount: respList[i].BiddingCount,
- ProjectCount: respList[i].ProjectCount,
- BidAmountCount: respList[i].BidAmountCount,
- }
- // 存redis
- b, err := json.Marshal(tmp)
- if err == nil {
- redis.PutBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, respList[i].Buyer), &b, BuyerSupplyInfoRedisTime+GetRand(60))
- }
- }
- }(resp.Data.List)
- return resp
- }
- // 获取项目数量 采购单位规模
- func getBuyerProjectCache(buyer string) (rs *supplyDataStruct) {
- bs, err := redis.GetBytes("other", fmt.Sprintf(BuyerProjectInfoRedisKey, buyer))
- if err == nil && bs != nil && len(*bs) > 0 {
- if err := json.Unmarshal(*bs, &rs); err != nil {
- logx.Info("获取redis缓存,序列化异常")
- } else {
- return rs
- }
- }
- return
- }
- // BuyerSupplyInfo 补充字段
- func BuyerSupplyInfo(buyerNames []string) (resp *bxbuyer.BuyerSupplyResp) {
- resp = &bxbuyer.BuyerSupplyResp{}
- start := time.Now()
- // buyerNames
- //buyerNames 是否存在缓存 数据
- //如果没有 放到一个新的 []string
- needSearchBuyer := []string{}
- cacheMap := map[string]supplyDataStruct{}
- buyerMap := map[string]supplyDataStruct{}
- for i := 0; i < len(buyerNames); i++ {
- bs, err := redis.GetBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, buyerNames[i]))
- if err == nil && bs != nil && len(*bs) > 0 {
- tmp := supplyDataStruct{}
- if err := json.Unmarshal(*bs, &tmp); err == nil {
- cacheMap[buyerNames[i]] = tmp // 拿到缓存的数据 采购规模 项目数量 联系人数量 招标动态数量
- } else {
- // 查缓存
- cacheProject := getBuyerProjectCache(buyerNames[i])
- if cacheProject != nil {
- buyerMap[buyerNames[i]] = *cacheProject
- } else {
- needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查采购规模和项目数量
- }
- }
- } else {
- // 查缓存
- cacheProject := getBuyerProjectCache(buyerNames[i])
- if cacheProject != nil {
- buyerMap[buyerNames[i]] = *cacheProject
- } else {
- needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查采购规模和项目数量
- }
- }
- }
- if len(needSearchBuyer) > 0 {
- t1 := time.Now()
- query := SupplyDataQuery(buyerNames) // 项目数量、采购规模
- // 聚合查
- aggs := GetAggs(P_INDEX, P_TYPE, query)
- logx.Info("查询语句:", query)
- logx.Info("项目数量采购规模查询耗时:", time.Since(t1))
- type BuyerAggStruct struct {
- Buckets []struct {
- Key string `json:"key,omitempty"`
- Doc_count int64 `json:"doc_count,omitempty"`
- BidAmountCount struct {
- Value float32 `json:"value,omitempty"`
- } `json:"bidAmountCount"`
- } `json:"buckets"`
- }
- var buyerBuckets = BuyerAggStruct{}
- // 处理成map 用于后面格式化数据
- if aggs != nil && aggs["buyerBuckets"] != nil {
- bs, err := aggs["buyerBuckets"].MarshalJSON()
- if err != nil {
- resp.ErrCode = -1
- resp.ErrMsg = "获取数据异常"
- } else {
- if len(bs) == 0 {
- resp.ErrMsg = "暂无数据"
- } else {
- err := json.Unmarshal(bs, &buyerBuckets)
- logx.Info(err)
- if len(buyerBuckets.Buckets) > 0 {
- for _, v := range buyerBuckets.Buckets {
- buyerMap[v.Key] = supplyDataStruct{
- BidAmountCount: v.BidAmountCount.Value,
- ProjectCount: v.Doc_count,
- }
- }
- }
- }
- }
- }
- }
- ch := make(chan int, 10)
- ch2 := make(chan int, 10)
- wg := &sync.WaitGroup{}
- for i := 0; i < len(buyerNames); i++ {
- buyer := buyerNames[i]
- resp.Data = append(resp.Data, &bxbuyer.SupplyData{
- Buyer: buyer,
- })
- // 先查缓存
- if cacheData, ok := cacheMap[buyer]; ok {
- resp.Data[i].BidAmountCount = cacheData.BidAmountCount
- resp.Data[i].ProjectCount = cacheData.ProjectCount
- resp.Data[i].BiddingCount = cacheData.BidCount
- resp.Data[i].ContactCount = cacheData.ContactCount
- continue
- }
- // 缓存里没有的再取查数据补充
- // 补充字段
- if supplyData, ok := buyerMap[buyer]; ok {
- resp.Data[i].BidAmountCount = supplyData.BidAmountCount
- resp.Data[i].ProjectCount = supplyData.ProjectCount
- }
- ch2 <- 1
- wg.Add(1)
- go func(list *bxbuyer.SupplyData, buyer string) {
- defer func() {
- <-ch2
- wg.Done()
- }()
- list.ContactCount = GetProjectContactCount(buyer) // 补充联系人字段
- }(resp.Data[i], buyer)
- ch <- 1
- wg.Add(1)
- go func(list *bxbuyer.SupplyData, buyer string) {
- defer func() {
- <-ch
- wg.Done()
- }()
- list.BiddingCount = GetNewBiddingCount(buyer)
- }(resp.Data[i], buyer)
- }
- wg.Wait()
- logx.Info(" 整体耗时:", time.Since(start))
- //得到所有数据,包括 redis里的,再存一下
- go func(respList []*bxbuyer.SupplyData) {
- for i := 0; i < len(respList); i++ {
- tmp := supplyDataStruct{
- ContactCount: respList[i].ContactCount,
- BidCount: respList[i].BiddingCount,
- ProjectCount: respList[i].ProjectCount,
- BidAmountCount: respList[i].BidAmountCount,
- }
- // 存redis
- b, err := json.Marshal(tmp)
- if err == nil {
- redis.PutBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, respList[i].Buyer), &b, BuyerSupplyInfoRedisTime+GetRand(60))
- }
- }
- }(resp.Data)
- return
- }
- func GetProjectContactCount(buyerName string) int64 {
- start := time.Now()
- list := []string{}
- searchSql := fmt.Sprintf(`{"query":{"bool":{"filter":[{"term":{"buyer":"%s"}}]}},"_source":["list.buyerperson","list.buyertel"],"sort":[{"zbtime":"desc"}],"size":500}`, buyerName)
- projectList := elastic.Get(P_INDEX, P_TYPE, searchSql)
- logx.Info("GetProjectContactCount esget 耗时", time.Since(start), searchSql)
- if projectList == nil || len(*projectList) == 0 {
- return 0
- }
- //根据联系人和联系方式展示
- //多个项目同一个联系人;只展示最新项目
- //一个项目多个联系人;拆分展示
- repeatContacts := map[string]bool{}
- for _, rowData := range *projectList {
- mapList, ok := rowData["list"].([]interface{})
- if !ok || len(mapList) == 0 {
- continue
- }
- for i := len(mapList) - 1; i >= 0; i-- {
- thisMsg, ok := mapList[i].(map[string]interface{})
- if !ok || len(thisMsg) == 0 {
- continue
- }
- thisPhone, thisPerson := "", ""
- if thisPhone, _ = thisMsg["buyertel"].(string); thisPhone != "" {
- thisPerson, _ = thisMsg["buyerperson"].(string)
- }
- if thisPhone == "" { //联系人为空则不展示 dev4.7.3联系人为空展示此记录
- continue
- }
- //一个项目只选取一条公告联系人
- thisAddPerson := false
- //名字中多个联系人拆分
- for _, name := range strings.Split(thisPerson, ",") {
- thisName := strings.TrimSpace(name)
- if thisName == "" && thisAddPerson { //联系人为空则不展示
- continue
- }
- thisAddPerson = true
- repeatKey := fmt.Sprintf("%s_%s", thisName, thisPhone)
- if repeatContacts[repeatKey] {
- continue
- }
- repeatContacts[repeatKey] = true
- list = append(list, thisPhone)
- }
- if thisAddPerson {
- break
- }
- }
- }
- logx.Info("GetProjectContactCount 单次耗时:", time.Since(start))
- return int64(len(list))
- }
- func GetNewBiddingCount(buyer string) int64 {
- start := time.Now()
- if buyer == "" {
- return 0
- }
- var mustQuery []string
- st, et := getTimeRange()
- mustQuery = append(mustQuery, fmt.Sprintf(`{"range":{"publishtime":{"gte":%d,"lte":%d}}}`, st.Unix(), et.Unix()))
- mustQuery = append(mustQuery, fmt.Sprintf(`{"term": {"buyer": "%s"}}`, buyer))
- aa := fmt.Sprintf(`{"query":{"bool":{"must":[%s]}}}`, strings.Join(mustQuery, ","))
- count := elastic.Count(biddingIndex, biddingType, aa)
- logx.Info("GetNewBiddingCount 单次耗时:", buyer, time.Since(start))
- return count
- }
- // 聚合查询
- func GetAggs(index, itype, query string) (aggs map[string]json.RawMessage) {
- aggs, _, _ = elastic.GetAggs(index, itype, query)
- return
- }
- type buyerInfo struct {
- Province string
- City string
- }
- // 潜在客户 获取省份和城市
- func GetBuyerInfo(buyerNames []string) (infoMap map[string]buyerInfo) {
- var buyerInfoQuery = `{"query": {"bool": {"must": [{"terms": {"%s": [%s]}}],"must_not": [],"should": []}},"from": 0,"size": 50,"sort": []}`
- query := fmt.Sprintf(buyerInfoQuery, "buyer_name", `"`+strings.Join(buyerNames, `","`)+`"`)
- list := *elastic.Get("buyer", "buyer", query)
- if list != nil {
- if len(list) > 0 {
- infoMap = map[string]buyerInfo{}
- for _, v := range list {
- infoMap[v["name"].(string)] = buyerInfo{
- Province: MC.If(v["province"] != nil, MC.ObjToString(v["province"]), "").(string),
- City: MC.If(v["city"] != nil, MC.ObjToString(v["city"]), "").(string),
- }
- }
- }
- } else {
- logx.Info("采购单位获取地区信息异常")
- }
- return
- }
- var fc = "follow_customer" //关注客户表
- // 采购单位是否作为客户已被关注
- func IsFollowd(buyerNames []string, userId string) (isFws map[string]bool) {
- queryMap := map[string]interface{}{
- "userId": userId,
- "name": map[string]interface{}{
- "$in": buyerNames,
- },
- }
- list, ok := IC.Mgo.Find(fc, queryMap, `{"_id":1}`, nil, false, -1, -1)
- if ok && len(*list) > 0 {
- isFws = map[string]bool{}
- for _, lv := range *list {
- if MC.ObjToString(lv["name"]) != "" {
- isFws[MC.ObjToString(lv["name"])] = true
- }
- }
- } else {
- logx.Info("采购单位是否已关注信息异常 or 未查到数据")
- }
- return
- }
- var (
- Entniche_customer = "entniche_customer"
- Entniche_user_customer = "entniche_user_customer"
- )
- // 领取状态
- func IsReceived(buyerNames []string, entUserId string) (isRws map[string]string) {
- //新加领取的客户id----保证领取的唯一性
- aa := fmt.Sprintf("SELECT ecn.id, ecn.name FROM %s ecn,%s euu WHERE ecn.id = euu.customer_id AND euu.user_id =? AND ecn.`name` IN ('%s') AND (euu.source_type =1 or euu.source_type=4)", Entniche_customer, Entniche_user_customer, strings.Join(buyerNames, "','"))
- log.Println(aa)
- receInfos := IC.MainMysql.SelectBySql(fmt.Sprintf("SELECT ecn.id, ecn.name FROM %s ecn,%s euu WHERE ecn.id = euu.customer_id AND euu.user_id =? AND ecn.`name` IN ('%s') AND (euu.source_type =1 or euu.source_type=4)", Entniche_customer, Entniche_user_customer, strings.Join(buyerNames, "','")), entUserId)
- if receInfos != nil {
- if len(*receInfos) > 0 {
- isRws = map[string]string{}
- for _, rv := range *receInfos {
- if MC.ObjToString(rv["name"]) != "" && strconv.Itoa(MC.IntAll(rv["id"])) != "" {
- isRws[MC.ObjToString(rv["name"])] = encrypt.SE.Encode2HexByCheck(strconv.Itoa(MC.IntAll(rv["id"])))
- }
- }
- }
- } else {
- logx.Info("采购单位是否已领取信息异常")
- }
- return
- }
- // 是否为空请求
- func CheckEmpty(in *bxbuyer.BuyerListReq) bool {
- if in.BuyerName == "" && len(in.BuyerClass) == 0 && len(in.Province) == 0 && len(in.City) == 0 && in.IsContact == 0 {
- return true
- }
- return false
- }
- //缓存数据查询
- // 获取采购单位查询query
- func BuyerListRedisCacheQuery() (qstr string) {
- qstr = `{"size":%d,"query":{"bool":{"must":[],"must_not":[{"term":{"buyer_name":""}}]}},"sort":[{"updatetime":"desc"}]}`
- return fmt.Sprintf(qstr, IC.C.BuyerSearchLimit)
- }
|