package model import ( "encoding/json" "fmt" IC "jyBXBuyer/rpc/init" "jyBXBuyer/rpc/type/bxbuyer" "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" ) type BScope struct { Keyword []string `json:"keyword"` AdditionalWords []string `json:"additionalWords"` ExcludedWords []string `json:"excludedWords"` } //获取采购单位查询query func BuyerListQuery(in *bxbuyer.BuyerListReq) (qstr string) { query_bool_must_and := `{"bool": {"must": [%s]%s}}` multi_match := `{"multi_match": {"query": %s,"type": "phrase", "fields": [%s]}}` query := `{"size": 0,"query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer": ""}}],"should":[%s],"minimum_should_match": %d}},%s}` //21.1.20 为和画像保持一致 数据组要求 budget 改成 bidamount query_aggs := `"aggs": {"group_field": {"terms": {"field": %s,"size": %d%s},"aggs": {"count": {"sum": {"field": "bidamount"}}}}}` query_sort := `,"order": {"count": "desc"}` query_bool_must := `{"terms":{"%s":[%s]}}` query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}` bools := []string{} musts := []string{} musts_should := []string{} //省份 if len(in.Province) > 0 { musts_should = append(musts_should, fmt.Sprintf(`{"terms":{"area":["%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 len(in.BuyerName) > 0 { entNameQuery := `{"match_phrase":{"buyer.mbuyer":"` + in.BuyerName + `"}}` musts = append(musts, entNameQuery) } //采购单位类型 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) } //行业 industry := in.Industry if len(industry) > 0 { musts = append(musts, fmt.Sprintf(query_bool_must, "subscopeclass", `"`+strings.Join(industry, `","`)+`"`)) } if len(in.Customer) > 0 { entcustomerClass := `{"terms":{"buyer":[` for k, v := range in.Customer { if k > 0 { entcustomerClass += `,` } entcustomerClass += `"` + v + `"` } entcustomerClass += `]}}` musts = append(musts, entcustomerClass) } //业务范围 boolsNum := 0 if in.BusinessScope != "" { var BScopes = []BScope{} json.Unmarshal([]byte(in.BusinessScope), &BScopes) boolsNum = 1 findfields := `"projectname.pname","purchasing"` multi_match = fmt.Sprintf(multi_match, "%s", findfields) for _, v := range BScopes { shoulds := []string{} must_not := []string{} //关键词 if len(v.Keyword) > 0 { for _, kv := range v.Keyword { shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+kv+"\"")) } } //附加词 if len(v.AdditionalWords) > 0 { for _, av := range v.AdditionalWords { shoulds = append(shoulds, fmt.Sprintf(multi_match, "\""+av+"\"")) } } if len(v.ExcludedWords) > 0 { //排除词 for _, ev := range v.ExcludedWords { must_not = append(must_not, fmt.Sprintf(multi_match, "\""+ev+"\"")) } } //添加 if len(shoulds) > 0 { notStr := "" if len(must_not) > 0 { notStr = fmt.Sprintf(`,"must_not":[%s]`, strings.Join(must_not, ",")) } bools = append(bools, fmt.Sprintf(query_bool_must_and, strings.Join(shoulds, ","), notStr)) } } } query_aggs = fmt.Sprintf(query_aggs, `"buyer"`, IC.C.BuyerCount, "%s") if in.SortRule == 0 { //项目总数排序 query_sort = "" } query_aggs = fmt.Sprintf(query_aggs, query_sort) qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(bools, ","), boolsNum, query_aggs) return } const ( P_INDEX = "projectset" P_TYPE = "projectset" P_redis_time = 15 * 24 * 60 * 60 //redis存15天 P_redis_key = "buyerListCache" ) //查询采购单位列表 func GetBuyerList(qstr string, in *bxbuyer.BuyerListReq, isCache bool) (resp *bxbuyer.BuyerListResp) { t1 := time.Now() aggs := GetAggs(P_INDEX, P_TYPE, qstr) resp = &bxbuyer.BuyerListResp{ Data: &bxbuyer.BuyerData{}, } type GroupStruct struct { Buckets []struct { Key string `json:"key,omitempty"` Doc_count int64 `json:"doc_count,omitempty"` Count struct { Value float64 `json:"value,omitempty"` } `json:"count"` } `json:"buckets"` } var group = GroupStruct{} if aggs != nil && aggs["group_field"] != nil { bs, err := aggs["group_field"].MarshalJSON() if err != nil { resp.ErrCode = -1 resp.ErrMsg = "获取数据异常" } else { if len(bs) == 0 { resp.ErrMsg = "暂无数据" } else { json.Unmarshal(bs, &group) if len(group.Buckets) > 0 { for _, v := range group.Buckets { var list = &bxbuyer.BuyerList{} list.Buyer = v.Key list.Budget = v.Count.Value list.PCount = v.Doc_count resp.Data.List = append(resp.Data.List, list) } } } } } resp.Data.Count = int64(len(resp.Data.List)) logx.Info("=---count---===", resp.Data.Count) if len(resp.Data.List) > 0 { var wg sync.WaitGroup //省份和城市 是否查询已关注信息 是否查询已领取信息 //企业信用库qyxy_std 和es buyer库 查询省份和城市 var fiftyArr = []*bxbuyer.BuyerList{} var buyerNames = []string{} for bk, bv := range resp.Data.List { fiftyArr = append(fiftyArr, bv) buyerNames = append(buyerNames, bv.Buyer) if (bk+1)%50 == 0 || len(resp.Data.List) == bk+1 { wg.Add(1) go func(wg *sync.WaitGroup, fiftyArr []*bxbuyer.BuyerList, buyerNames []string, icf, icr bool, userId, entUserId string) { //省份城市 关注状态 领取状态 infoMap := GetBuyerInfo(buyerNames) //关注状态 isFws := map[string]bool{} if icf { isFws = IsFollowd(buyerNames, userId) } //领取状态 isRws := map[string]string{} if icr { isRws = IsReceived(buyerNames, entUserId) } //log.Println("---:", isRws) for _, fv := range fiftyArr { fv.Province = infoMap[fv.Buyer].Province fv.City = infoMap[fv.Buyer].City if icf { fv.IsFollowed = isFws[fv.Buyer] } if icr { if isRws[fv.Buyer] != "" { fv.RecId = isRws[fv.Buyer] fv.IsReceived = true } } } wg.Done() }(&wg, fiftyArr, buyerNames, in.IsCheckFollow, in.IsCheckReceive, in.UserId, in.EntUserId) fiftyArr = []*bxbuyer.BuyerList{} buyerNames = []string{} } } wg.Wait() } logx.Info("耗时;", time.Since(t1).Seconds(), time.Since(t1).Microseconds()) return } //聚合查询 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 && list != nil { if 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("采购单位是否已关注信息异常") } return } var ( Entniche_customer = "entniche_customer" Entniche_user_customer = "entniche_user_customer" ) //领取状态 func IsReceived(buyerNames []string, entUserId string) (isRws map[string]string) { //新加领取的客户id----保证领取的唯一性 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 && len(in.Industry) == 0 && in.BusinessScope == "" && len(in.Customer) == 0 { return true } return false } //缓存数据查询 //获取采购单位查询query func BuyerListRedisCacheQuery() (qstr string) { query := `{"size": 0,"query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer": ""}}],"should":[],"minimum_should_match": %d}},%s}` //21.1.20 为和画像保持一致 数据组要求 budget 改成 bidamount query_aggs := `"aggs": {"group_field": {"terms": {"field": %s,"size": %d%s},"aggs": {"count": {"sum": {"field": "bidamount"}}}}}` query_sort := `,"order": {"count": "desc"}` musts := []string{} boolsNum := 0 entcustomerClass := `{"terms":{"buyer":[` for k, v := range IC.C.DefaultBuyerNames { if k > 0 { entcustomerClass += `,` } entcustomerClass += `"` + v + `"` } entcustomerClass += `]}}` musts = append(musts, entcustomerClass) query_aggs = fmt.Sprintf(query_aggs, `"buyer"`, len(IC.C.DefaultBuyerNames), "%s") query_aggs = fmt.Sprintf(query_aggs, query_sort) qstr = fmt.Sprintf(query, strings.Join(musts, ","), boolsNum, query_aggs) logx.Info("qstr:", qstr) return }