Sfoglia il codice sorgente

feat:商机管理采购单位

wangshan 3 anni fa
parent
commit
9bdf40b269

+ 1 - 1
jyBXBuyer/README.md

@@ -2,7 +2,7 @@
 
 #### 接口文档地址
 ```
-https://yapi.jydev.jianyu360.com/project/63/interface/api/cat_96
+https://yapi.jydev.jianyu360.com/project/63/interface/api/cat_224
 ```
 #
 ```

+ 16 - 13
jyBXBuyer/api/bxbuyer.api

@@ -9,19 +9,22 @@ info (
 
 type (
 	buyerListReq {
-		Province       []string      `json:"province"`       //省份
-		City           []string      `json:"city"`           //城市
-		BuyerClass     []string      `json:"buyerClass"`     //客户类型(采购单位行业)
-		Industry       []string      `json:"industry"`       //行业分类(信息行业)
-		BusinessScope  []interface{} `json:"businessScope"`  //业务范围(关键词 附加词 排除词)
-		SortRule       int           `json:"sortRule"`       //排序规则
-		KeysWords      string        `json:"keysWords"`      //企业名称
-		AppId          string        `json:"appId"`          //剑鱼10000
-		PageNum        int64         `json:"pageNum"`        //当前页码
-		PageSize       int64         `json:"pageSize"`       //每页数据量
-		UserType       string        `path:"userType"`       //用户标签
-		IsCheckFollow  bool          `json:"isCheckFollow"`  //是否查询关注信息(商机管理用户)
-		IsCheckReceive bool          `json:"isCheckReceive"` //是否查询已领取(商机管理用户)
+		Province       []string `json:"province"`       //省份
+		City           []string `json:"city"`           //城市
+		BuyerClass     []string `json:"buyerClass"`     //客户类型(采购单位行业)
+		Industry       []string `json:"industry"`       //行业分类(信息行业)
+		BusinessScope  string   `json:"businessScope"`  //业务范围(关键词 附加词 排除词)
+		BuyerName      string   `json:"buyerName"`      //采购单位名称
+		AppId          string   `json:"appId"`          //剑鱼10000
+		UserType       string   `path:"userType"`       //用户标签
+		IsCheckFollow  bool     `json:"isCheckFollow"`  //是否查询关注信息(商机管理用户)
+		IsCheckReceive bool     `json:"isCheckReceive"` //是否查询已领取(商机管理用户)
+		UserId         string   `header:"userId"`       //用户id
+		EntId          string   `header:"entId"`        //企业id
+		EntUserId      string   `header:"entUserId"`    //商机管理企业用户id
+		//SortRule       int64    `json:"sortRule"`       //排序规则
+		//PageNum        int64    `json:"pageNum"`        //当前页码
+		//PageSize       int64    `json:"pageSize"`       //每页数据量
 	}
 	//
 	commonResp {

+ 38 - 14
jyBXBuyer/api/bxbuyer.go

@@ -1,31 +1,55 @@
 package main
 
 import (
-	"flag"
+	MC "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/endless"
+	"bp.jydev.jianyu360.cn/BaseService/gateway/core/node"
 	"fmt"
+	IC "jyBXBuyer/api/init"
+	"log"
+	"net/http"
+	"os"
+	"os/signal"
+	"syscall"
 
-	"jyBXBuyer/api/internal/config"
 	"jyBXBuyer/api/internal/handler"
 	"jyBXBuyer/api/internal/svc"
 
-	"github.com/zeromicro/go-zero/core/conf"
 	"github.com/zeromicro/go-zero/rest"
 )
 
-var configFile = flag.String("f", "etc/bxbuyer-api.yaml", "the config file")
-
 func main() {
-	flag.Parse()
-
-	var c config.Config
-	conf.MustLoad(*configFile, &c)
-
-	ctx := svc.NewServiceContext(c)
-	server := rest.MustNewServer(c.RestConf)
+	//注册代理服务
+	closeNotify, err := node.NewNode(IC.C.Gateway.Etcd...).Register(IC.C.Gateway.ServerCode, MC.InterfaceToStr(IC.C.Port))
+	if err != nil {
+		panic(err)
+	}
+	//
+	go func() {
+		err := endless.ListenAndServe(":"+MC.InterfaceToStr(IC.C.Webrpcport), nil, func() {})
+		if err != nil {
+			log.Println("ListenAndServe: ", err)
+		}
+	}()
+	ctx := svc.NewServiceContext(IC.C)
+	server := rest.MustNewServer(IC.C.RestConf)
 	defer server.Stop()
+	//全局中间件
+	server.Use(func(next http.HandlerFunc) http.HandlerFunc {
+		return func(w http.ResponseWriter, r *http.Request) {
+			defer func() {
+				MC.AddMgoLogs(IC.MgoLog, r, IC.C.MgoLogsName, IC.ExcludeUrl, IC.C.MgoLogsCount)
+			}()
+			next.ServeHTTP(w, r)
+		}
+	})
 
 	handler.RegisterHandlers(server, ctx)
-
-	fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
+	fmt.Printf("Starting server at %s:%d...\n", IC.C.Host, IC.C.Port)
 	server.Start()
+
+	quit := make(chan os.Signal, 1)
+	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+	<-quit
+	closeNotify()
 }

+ 1 - 1
jyBXBuyer/api/init/init.go

@@ -11,7 +11,7 @@ import (
 	"regexp"
 )
 
-var configFile = flag.String("cf", "etc/bxcore-api.yaml", "the config file")
+var configFile = flag.String("cf", "etc/bxbuyer-api.yaml", "the config file")
 
 var C config.Config
 

+ 37 - 2
jyBXBuyer/api/internal/logic/searchListLogic.go

@@ -2,6 +2,7 @@ package logic
 
 import (
 	"context"
+	"jyBXBuyer/rpc/type/bxbuyer"
 	"net/http"
 
 	"jyBXBuyer/api/internal/svc"
@@ -27,7 +28,41 @@ func NewSearchListLogic(ctx context.Context, svcCtx *svc.ServiceContext, r *http
 }
 
 func (l *SearchListLogic) SearchList(req *types.BuyerListReq) (resp *types.CommonResp, err error) {
-	// todo: add your logic here and delete this line
-
+	if req.EntUserId == "" {
+		req.IsCheckReceive = false
+	}
+	if req.UserId == "" {
+		req.IsCheckFollow = false
+	}
+	res, err0 := l.svcCtx.Buyer.BuyerList(l.ctx, &bxbuyer.BuyerListReq{
+		AppId:          req.AppId,
+		PageNum:        req.PageNum,
+		PageSize:       req.PageSize,
+		BuyerName:      req.BuyerName,
+		Province:       req.Province,
+		City:           req.City,
+		BusinessScope:  req.BusinessScope,
+		SortRule:       req.SortRule,
+		Industry:       req.Industry,
+		BuyerClass:     req.BuyerClass,
+		IsCheckFollow:  req.IsCheckFollow,
+		IsCheckReceive: req.IsCheckReceive,
+		UserType:       req.UserType,
+		UserId:         l.r.Header.Get("userId"),
+		EntId:          req.EntId,
+		EntUserId:      req.EntUserId,
+	})
+	if err0 != nil {
+		return &types.CommonResp{
+			Err_code: -1,
+			Err_msg:  "错误",
+			Data:     nil,
+		}, nil
+	}
+	return &types.CommonResp{
+		Err_code: res.ErrCode,
+		Err_msg:  res.ErrMsg,
+		Data:     res.Data,
+	}, nil
 	return
 }

+ 4 - 0
jyBXBuyer/api/internal/svc/serviceContext.go

@@ -1,15 +1,19 @@
 package svc
 
 import (
+	"github.com/zeromicro/go-zero/zrpc"
 	"jyBXBuyer/api/internal/config"
+	"jyBXBuyer/rpc/bxbuyer"
 )
 
 type ServiceContext struct {
 	Config config.Config
+	Buyer  bxbuyer.Bxbuyer
 }
 
 func NewServiceContext(c config.Config) *ServiceContext {
 	return &ServiceContext{
 		Config: c,
+		Buyer:  bxbuyer.NewBxbuyer(zrpc.MustNewClient(c.Buyer)),
 	}
 }

+ 16 - 13
jyBXBuyer/api/internal/types/types.go

@@ -2,19 +2,22 @@
 package types
 
 type BuyerListReq struct {
-	Area           []string      `json:"area"`           //省份
-	City           []string      `json:"city"`           //城市
-	BuyerClass     []string      `json:"buyerClass"`     //客户类型(采购单位行业)
-	Industry       []string      `json:"industry"`       //行业分类(信息行业)
-	BusinessScope  []interface{} `json:"businessScope"`  //业务范围(关键词 附加词 排除词)
-	SortRule       int           `json:"sortRule"`       //排序规则
-	KeysWords      string        `json:"keysWords"`      //企业名称
-	AppId          string        `json:"appId"`          //剑鱼10000
-	PageNum        int64         `json:"pageNum"`        //当前页码
-	PageSize       int64         `json:"pageSize"`       //每页数据量
-	UserType       string        `path:"userType"`       //用户标签
-	IsCheckFollow  bool          `json:"isCheckFollow"`  //是否查询关注信息(商机管理用户)
-	IsCheckReceive bool          `json:"isCheckReceive"` //是否查询已领取(商机管理用户)
+	Province       []string `json:"province"`       //省份
+	City           []string `json:"city"`           //城市
+	BuyerClass     []string `json:"buyerClass"`     //客户类型(采购单位行业)
+	Industry       []string `json:"industry"`       //行业分类(信息行业)
+	BusinessScope  string   `json:"businessScope"`  //业务范围(关键词 附加词 排除词)
+	SortRule       int64    `json:"sortRule"`       //排序规则
+	BuyerName      string   `json:"buyerName"`      //采购单位名称
+	AppId          string   `json:"appId"`          //剑鱼10000
+	PageNum        int64    `json:"pageNum"`        //当前页码
+	PageSize       int64    `json:"pageSize"`       //每页数据量
+	UserType       string   `path:"userType"`       //用户标签
+	IsCheckFollow  bool     `json:"isCheckFollow"`  //是否查询关注信息(商机管理用户)
+	IsCheckReceive bool     `json:"isCheckReceive"` //是否查询已领取(商机管理用户)
+	UserId         string   `header:"userId"`       //用户id
+	EntId          string   `header:"entId"`        //企业id
+	EntUserId      string   `header:"entUserId"`    //商机管理企业用户id
 }
 
 type CommonResp struct {

+ 2 - 0
jyBXBuyer/go.sum

@@ -917,6 +917,8 @@ gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
 gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/olivere/elastic.v1 v1.0.1 h1:ZoJwTKCI0jJdVptoGB0QEFt/4bDUs6A5Pjrmn/Zb+5g=
+gopkg.in/olivere/elastic.v1 v1.0.1/go.mod h1:sMIrW2Y2hS8bEAqdTvdcrNN/KV21XXOfjdi4tHxwVnI=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

+ 11 - 9
jyBXBuyer/rpc/bxbuyer.proto

@@ -7,18 +7,20 @@ message BuyerListReq {
   string appId = 1;//剑鱼默认10000
   int64  pageNum = 2;//当前页码
   int64  pageSize = 3;//每页数量
-  string  keyWords = 4;//关键词
-  string  province = 5;//省份
-  string  city = 6;//城市
+  string  buyerName = 4;//采购单位名称
+  repeated string  province = 5;//省份
+  repeated string  city = 6;//城市
   string  businessScope = 7;//关键词 附加词 排除词
   int64  sortRule = 8;//排序规则
   bool  isCheckFollow = 9;//是否查询关注信息(商机管理用户)
   bool  isCheckReceive = 10;//是否查询已领取(商机管理用户)
-  string industry = 11;//行业
-  string buyerClass = 12;//采购单位类型
+  repeated string  industry = 11;//行业
+  repeated string  buyerClass = 12;//采购单位类型
   string  userId = 13;
   string  userType = 14;//用户状态 fType:免费用户	pType:付费用户	vType:超级订阅用户	mType:大会员用户	eType:商机管理用户
   string  platform = 15;//请求平台
+  string entId = 16;//企业id
+  string entUserId = 17;//商机管理用户id
 }
 
 message BuyerListResp {
@@ -33,12 +35,12 @@ message BuyerData {
 
 message  BuyerList {
   string  buyer = 1;//采购单位名称
-  float  budget = 2;//预算
+  double  budget = 2;//预算
   string  province = 3;//省份
   string  city = 4;//城市
-  string  pCount = 5;//项目数量
-  string  isFollowed = 6;//是否关注
-  string  isReceive = 7;//是否已领取
+  int64  pCount = 5;//项目数量
+  bool  isFollowed = 6;//是否关注
+  bool  isReceived = 7;//是否已领取
 }
 
 service Bxbuyer {

+ 23 - 0
jyBXBuyer/rpc/etc/bxbuyer.yaml

@@ -5,3 +5,26 @@ Etcd:
   - 127.0.0.1:2379
   Key: bxbuyer.rpc
 Webrpcport: 8018
+BuyerCount: 500
+DefaultBuyerNames:
+    - "吉林省农村信用社联合社"
+    - "包头职业技术学院"
+    - "中国民生银行股份有限公司"
+    - "广东烟草梅州市有限公司"
+    - "宁波市自然资源和规划局"
+    - "正数网络技术有限公司"
+    - "浙江创联信息技术股份有限公司"
+    - "甘肃省农村信用社联合社"
+    - "广西壮族自治区自然资源厅"
+    - "华数传媒网络有限公司"
+    - "无锡地铁集团有限公司"
+    - "天津银行股份有限公司"
+    - "广州信息投资有限公司"
+    - "国联证券股份有限公司"
+    - "北京航空航天大学宁波创新研究院"
+    - "湖北省卫生健康委员会"
+    - "上海浦东发展银行股份有限公司信用卡中心"
+    - "上海市房屋管理局"
+    - "长三角金融科技有限公司"
+    - "华能信息技术有限公司"
+    - "浙江华数广电网络股份有限公司"

+ 1 - 9
jyBXBuyer/rpc/etc/db.yaml

@@ -16,12 +16,4 @@ mongo:
     main:
         dbName: qfw
         size: 5
-        address: 192.168.3.206:27080
-    bidding:
-        address: 192.168.3.206:27001
-        size: 5
-        dbName: qfw_data
-        collection: bidding
-        collectionChange: bidding_back
-        userName: jyDevGroup
-        password: jy@DevGroup
+        address: 192.168.3.206:27080

+ 2 - 15
jyBXBuyer/rpc/init/db.go

@@ -16,9 +16,8 @@ import (
 )
 
 var (
-	MainMysql  *mysql.Mysql
-	Mgo        mongodb.MongodbSim
-	MgoBidding mongodb.MongodbSim
+	MainMysql *mysql.Mysql
+	Mgo       mongodb.MongodbSim
 )
 
 //
@@ -33,18 +32,6 @@ func MongoDBInit(em *entity.Mongo) {
 		}
 		Mgo.InitPool()
 	}
-	//
-	if em.Bidding.Address != "" {
-		logx.Info("--初始化 mongodb bidding--")
-		MgoBidding = mongodb.MongodbSim{
-			MongodbAddr: em.Bidding.Address,
-			Size:        em.Bidding.Size,
-			DbName:      em.Bidding.DbName,
-			UserName:    em.Bidding.UserName,
-			Password:    em.Bidding.Password,
-		}
-		MgoBidding.InitPool()
-	}
 }
 
 //

+ 1 - 1
jyBXBuyer/rpc/init/init.go

@@ -9,7 +9,7 @@ import (
 	"jyBXBuyer/rpc/internal/config"
 )
 
-var configFile = flag.String("cf", "etc/bxcore.yaml", "the config file")
+var configFile = flag.String("cf", "etc/bxbuyer.yaml", "the config file")
 var C config.Config
 var err error
 

+ 3 - 1
jyBXBuyer/rpc/internal/config/config.go

@@ -7,7 +7,9 @@ import (
 
 type Config struct {
 	zrpc.RpcServerConf
-	Webrpcport int64
+	Webrpcport        int64
+	BuyerCount        int64
+	DefaultBuyerNames []string
 }
 
 type Db struct {

+ 38 - 6
jyBXBuyer/rpc/internal/logic/buyerlistlogic.go

@@ -1,12 +1,14 @@
 package logic
 
 import (
+	"app.yhyue.com/moapp/jybase/redis"
 	"context"
-
+	"encoding/json"
+	"github.com/zeromicro/go-zero/core/logx"
 	"jyBXBuyer/rpc/internal/svc"
+	"jyBXBuyer/rpc/model"
 	"jyBXBuyer/rpc/type/bxbuyer"
-
-	"github.com/zeromicro/go-zero/core/logx"
+	"log"
 )
 
 type BuyerListLogic struct {
@@ -25,7 +27,37 @@ func NewBuyerListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BuyerLi
 
 // 采购单位搜索
 func (l *BuyerListLogic) BuyerList(in *bxbuyer.BuyerListReq) (*bxbuyer.BuyerListResp, error) {
-	// todo: add your logic here and delete this line
-
-	return &bxbuyer.BuyerListResp{}, nil
+	log.Println("----:", model.CheckEmpty(in))
+	query := ""
+	resp := &bxbuyer.BuyerListResp{}
+	if model.CheckEmpty(in) {
+		//获取缓存数据
+		var isBool = true
+		bs, err := redis.GetBytes("other", model.P_redis_key)
+		if err == nil && bs != nil && len(*bs) > 0 {
+			isBool = false
+			if err := json.Unmarshal(*bs, &resp.Data); err != nil {
+				isBool = true
+				logx.Info("获取redis缓存,序列化异常")
+			}
+		}
+		if isBool {
+			query = model.BuyerListRedisCacheQuery()
+			resp = model.GetBuyerList(query, in)
+			b, err := json.Marshal(resp.Data)
+			if err == nil {
+				redis.PutBytes("other", model.P_redis_key, &b, model.P_redis_time)
+			} else {
+				logx.Info("缓存数据 序列化异常")
+			}
+		}
+	} else {
+		query = model.BuyerListQuery(in)
+		resp = model.GetBuyerList(query, in)
+	}
+	return &bxbuyer.BuyerListResp{
+		Data:    resp.Data,
+		ErrMsg:  resp.ErrMsg,
+		ErrCode: resp.ErrCode,
+	}, nil
 }

+ 342 - 0
jyBXBuyer/rpc/model/buyerListBYEs.go

@@ -0,0 +1,342 @@
+package model
+
+import (
+	MC "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/esv1"
+	"encoding/json"
+	"fmt"
+	"github.com/zeromicro/go-zero/core/logx"
+	IC "jyBXBuyer/rpc/init"
+	"jyBXBuyer/rpc/type/bxbuyer"
+	"log"
+	"runtime"
+	"strings"
+	"sync"
+)
+
+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]}}`
+	bools := []string{}
+	musts := []string{}
+	//省份
+	if len(in.Province) > 0 {
+		musts = append(musts, fmt.Sprintf(`{"terms":{"area":[%s]}}`, strings.Join(in.Province, ",")))
+	}
+	//城市
+	if len(in.City) > 0 {
+		musts = append(musts, fmt.Sprintf(`{"terms":{"city":[%s]}}`, strings.Join(in.City, ",")))
+	}
+	//采购单位名称
+	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, `","`)+`"`))
+	}
+	//业务范围
+	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) (resp *bxbuyer.BuyerListResp) {
+	aggs, count := GetAggs(P_INDEX, P_TYPE, qstr)
+	log.Println(aggs, "=------===", count)
+	if count > int64(len(IC.C.DefaultBuyerNames)) {
+		count = int64(len(IC.C.DefaultBuyerNames))
+	}
+	resp = &bxbuyer.BuyerListResp{
+		Data: &bxbuyer.BuyerData{},
+	}
+	resp.Data.Count = count
+	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)
+					}
+				}
+			}
+		}
+	}
+	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]bool{}
+					if icr {
+						isRws = IsReceived(buyerNames, entUserId)
+					}
+					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 {
+							fv.IsReceived = isRws[fv.Buyer]
+						}
+					}
+					wg.Done()
+				}(&wg, fiftyArr, buyerNames, in.IsCheckFollow, in.IsCheckReceive, in.UserId, in.EntUserId)
+				fiftyArr = []*bxbuyer.BuyerList{}
+				buyerNames = []string{}
+			}
+		}
+		wg.Wait()
+	}
+	return
+}
+
+//聚合查询
+func GetAggs(index, itype, query string) (aggs map[string]*json.RawMessage, count int64) {
+	count = elastic.Count(index, itype, query)
+	defer MC.Catch()
+	client := elastic.GetEsConn()
+	defer func() {
+		go elastic.DestoryEsConn(client)
+	}()
+	if client != nil {
+		defer func() {
+			if r := recover(); r != nil {
+				for skip := 1; ; skip++ {
+					_, file, line, ok := runtime.Caller(skip)
+					if !ok {
+						break
+					}
+					go log.Printf("%v,%v\n", file, line)
+				}
+			}
+		}()
+		searchResult, err := client.Search().Index(index).Type(itype).Source(query).Do()
+		if searchResult.TimedOut {
+			//请求超时
+			log.Println(err, "____________:::", searchResult.TimedOut)
+			return
+		}
+		if err != nil {
+			log.Println("从ES查询出错", err.Error())
+		}
+		aggs = searchResult.Aggregations
+	}
+	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 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 && 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]bool) {
+	receInfos := IC.MainMysql.SelectBySql(fmt.Sprintf("SELECT  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 len(*receInfos) > 0 {
+		isRws = map[string]bool{}
+		for _, rv := range *receInfos {
+			if MC.ObjToString(rv["name"]) != "" {
+				isRws[MC.ObjToString(rv["name"])] = true
+			}
+		}
+	} 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 == "" {
+		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
+}

+ 113 - 94
jyBXBuyer/rpc/type/bxbuyer/bxbuyer.pb.go

@@ -30,21 +30,23 @@ type BuyerListReq struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	AppId          string `protobuf:"bytes,1,opt,name=appId,proto3" json:"appId,omitempty"`                     //剑鱼默认10000
-	PageNum        int64  `protobuf:"varint,2,opt,name=pageNum,proto3" json:"pageNum,omitempty"`                //当前页码
-	PageSize       int64  `protobuf:"varint,3,opt,name=pageSize,proto3" json:"pageSize,omitempty"`              //每页数量
-	KeyWords       string `protobuf:"bytes,4,opt,name=keyWords,proto3" json:"keyWords,omitempty"`               //关键词
-	Province       string `protobuf:"bytes,5,opt,name=province,proto3" json:"province,omitempty"`               //省份
-	City           string `protobuf:"bytes,6,opt,name=city,proto3" json:"city,omitempty"`                       //城市
-	BusinessScope  string `protobuf:"bytes,7,opt,name=businessScope,proto3" json:"businessScope,omitempty"`     //关键词 附加词 排除词
-	SortRule       int64  `protobuf:"varint,8,opt,name=sortRule,proto3" json:"sortRule,omitempty"`              //排序规则
-	IsCheckFollow  bool   `protobuf:"varint,9,opt,name=isCheckFollow,proto3" json:"isCheckFollow,omitempty"`    //是否查询关注信息(商机管理用户)
-	IsCheckReceive bool   `protobuf:"varint,10,opt,name=isCheckReceive,proto3" json:"isCheckReceive,omitempty"` //是否查询已领取(商机管理用户)
-	Industry       string `protobuf:"bytes,11,opt,name=industry,proto3" json:"industry,omitempty"`              //行业
-	BuyerClass     string `protobuf:"bytes,12,opt,name=buyerClass,proto3" json:"buyerClass,omitempty"`          //采购单位类型
-	UserId         string `protobuf:"bytes,13,opt,name=userId,proto3" json:"userId,omitempty"`
-	UserType       string `protobuf:"bytes,14,opt,name=userType,proto3" json:"userType,omitempty"` //用户状态 fType:免费用户	pType:付费用户	vType:超级订阅用户	mType:大会员用户	eType:商机管理用户
-	Platform       string `protobuf:"bytes,15,opt,name=platform,proto3" json:"platform,omitempty"` //请求平台
+	AppId          string   `protobuf:"bytes,1,opt,name=appId,proto3" json:"appId,omitempty"`                     //剑鱼默认10000
+	PageNum        int64    `protobuf:"varint,2,opt,name=pageNum,proto3" json:"pageNum,omitempty"`                //当前页码
+	PageSize       int64    `protobuf:"varint,3,opt,name=pageSize,proto3" json:"pageSize,omitempty"`              //每页数量
+	BuyerName      string   `protobuf:"bytes,4,opt,name=buyerName,proto3" json:"buyerName,omitempty"`             //采购单位名称
+	Province       []string `protobuf:"bytes,5,rep,name=province,proto3" json:"province,omitempty"`               //省份
+	City           []string `protobuf:"bytes,6,rep,name=city,proto3" json:"city,omitempty"`                       //城市
+	BusinessScope  string   `protobuf:"bytes,7,opt,name=businessScope,proto3" json:"businessScope,omitempty"`     //关键词 附加词 排除词
+	SortRule       int64    `protobuf:"varint,8,opt,name=sortRule,proto3" json:"sortRule,omitempty"`              //排序规则
+	IsCheckFollow  bool     `protobuf:"varint,9,opt,name=isCheckFollow,proto3" json:"isCheckFollow,omitempty"`    //是否查询关注信息(商机管理用户)
+	IsCheckReceive bool     `protobuf:"varint,10,opt,name=isCheckReceive,proto3" json:"isCheckReceive,omitempty"` //是否查询已领取(商机管理用户)
+	Industry       []string `protobuf:"bytes,11,rep,name=industry,proto3" json:"industry,omitempty"`              //行业
+	BuyerClass     []string `protobuf:"bytes,12,rep,name=buyerClass,proto3" json:"buyerClass,omitempty"`          //采购单位类型
+	UserId         string   `protobuf:"bytes,13,opt,name=userId,proto3" json:"userId,omitempty"`
+	UserType       string   `protobuf:"bytes,14,opt,name=userType,proto3" json:"userType,omitempty"`   //用户状态 fType:免费用户	pType:付费用户	vType:超级订阅用户	mType:大会员用户	eType:商机管理用户
+	Platform       string   `protobuf:"bytes,15,opt,name=platform,proto3" json:"platform,omitempty"`   //请求平台
+	EntId          string   `protobuf:"bytes,16,opt,name=entId,proto3" json:"entId,omitempty"`         //企业id
+	EntUserId      string   `protobuf:"bytes,17,opt,name=entUserId,proto3" json:"entUserId,omitempty"` //商机管理用户id
 }
 
 func (x *BuyerListReq) Reset() {
@@ -100,25 +102,25 @@ func (x *BuyerListReq) GetPageSize() int64 {
 	return 0
 }
 
-func (x *BuyerListReq) GetKeyWords() string {
+func (x *BuyerListReq) GetBuyerName() string {
 	if x != nil {
-		return x.KeyWords
+		return x.BuyerName
 	}
 	return ""
 }
 
-func (x *BuyerListReq) GetProvince() string {
+func (x *BuyerListReq) GetProvince() []string {
 	if x != nil {
 		return x.Province
 	}
-	return ""
+	return nil
 }
 
-func (x *BuyerListReq) GetCity() string {
+func (x *BuyerListReq) GetCity() []string {
 	if x != nil {
 		return x.City
 	}
-	return ""
+	return nil
 }
 
 func (x *BuyerListReq) GetBusinessScope() string {
@@ -149,18 +151,18 @@ func (x *BuyerListReq) GetIsCheckReceive() bool {
 	return false
 }
 
-func (x *BuyerListReq) GetIndustry() string {
+func (x *BuyerListReq) GetIndustry() []string {
 	if x != nil {
 		return x.Industry
 	}
-	return ""
+	return nil
 }
 
-func (x *BuyerListReq) GetBuyerClass() string {
+func (x *BuyerListReq) GetBuyerClass() []string {
 	if x != nil {
 		return x.BuyerClass
 	}
-	return ""
+	return nil
 }
 
 func (x *BuyerListReq) GetUserId() string {
@@ -184,6 +186,20 @@ func (x *BuyerListReq) GetPlatform() string {
 	return ""
 }
 
+func (x *BuyerListReq) GetEntId() string {
+	if x != nil {
+		return x.EntId
+	}
+	return ""
+}
+
+func (x *BuyerListReq) GetEntUserId() string {
+	if x != nil {
+		return x.EntUserId
+	}
+	return ""
+}
+
 type BuyerListResp struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -307,13 +323,13 @@ type BuyerList struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Buyer      string  `protobuf:"bytes,1,opt,name=buyer,proto3" json:"buyer,omitempty"`           //采购单位名称
-	Budget     float32 `protobuf:"fixed32,2,opt,name=budget,proto3" json:"budget,omitempty"`       //预算
-	Province   string  `protobuf:"bytes,3,opt,name=province,proto3" json:"province,omitempty"`     //省份
-	City       string  `protobuf:"bytes,4,opt,name=city,proto3" json:"city,omitempty"`             //城市
-	PCount     string  `protobuf:"bytes,5,opt,name=pCount,proto3" json:"pCount,omitempty"`         //项目数量
-	IsFollowed string  `protobuf:"bytes,6,opt,name=isFollowed,proto3" json:"isFollowed,omitempty"` //是否关注
-	IsReceive  string  `protobuf:"bytes,7,opt,name=isReceive,proto3" json:"isReceive,omitempty"`   //是否已领取
+	Buyer      string  `protobuf:"bytes,1,opt,name=buyer,proto3" json:"buyer,omitempty"`            //采购单位名称
+	Budget     float64 `protobuf:"fixed64,2,opt,name=budget,proto3" json:"budget,omitempty"`        //预算
+	Province   string  `protobuf:"bytes,3,opt,name=province,proto3" json:"province,omitempty"`      //省份
+	City       string  `protobuf:"bytes,4,opt,name=city,proto3" json:"city,omitempty"`              //城市
+	PCount     int64   `protobuf:"varint,5,opt,name=pCount,proto3" json:"pCount,omitempty"`         //项目数量
+	IsFollowed bool    `protobuf:"varint,6,opt,name=isFollowed,proto3" json:"isFollowed,omitempty"` //是否关注
+	IsReceived bool    `protobuf:"varint,7,opt,name=isReceived,proto3" json:"isReceived,omitempty"` //是否已领取
 }
 
 func (x *BuyerList) Reset() {
@@ -355,7 +371,7 @@ func (x *BuyerList) GetBuyer() string {
 	return ""
 }
 
-func (x *BuyerList) GetBudget() float32 {
+func (x *BuyerList) GetBudget() float64 {
 	if x != nil {
 		return x.Budget
 	}
@@ -376,90 +392,93 @@ func (x *BuyerList) GetCity() string {
 	return ""
 }
 
-func (x *BuyerList) GetPCount() string {
+func (x *BuyerList) GetPCount() int64 {
 	if x != nil {
 		return x.PCount
 	}
-	return ""
+	return 0
 }
 
-func (x *BuyerList) GetIsFollowed() string {
+func (x *BuyerList) GetIsFollowed() bool {
 	if x != nil {
 		return x.IsFollowed
 	}
-	return ""
+	return false
 }
 
-func (x *BuyerList) GetIsReceive() string {
+func (x *BuyerList) GetIsReceived() bool {
 	if x != nil {
-		return x.IsReceive
+		return x.IsReceived
 	}
-	return ""
+	return false
 }
 
 var File_bxbuyer_proto protoreflect.FileDescriptor
 
 var file_bxbuyer_proto_rawDesc = []byte{
 	0x0a, 0x0d, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
-	0x07, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x22, 0xc2, 0x03, 0x0a, 0x0c, 0x42, 0x75, 0x79,
+	0x07, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x22, 0xf8, 0x03, 0x0a, 0x0c, 0x42, 0x75, 0x79,
 	0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70,
 	0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12,
 	0x18, 0x0a, 0x07, 0x70, 0x61, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
 	0x52, 0x07, 0x70, 0x61, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67,
 	0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x67,
-	0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x57, 0x6f, 0x72, 0x64,
-	0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x57, 0x6f, 0x72, 0x64,
-	0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a,
-	0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x74,
-	0x79, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x53, 0x63, 0x6f,
-	0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65,
-	0x73, 0x73, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x72, 0x74, 0x52,
-	0x75, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x6f, 0x72, 0x74, 0x52,
-	0x75, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x6f,
-	0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x73, 0x43, 0x68,
-	0x65, 0x63, 0x6b, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x73, 0x43,
-	0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28,
-	0x08, 0x52, 0x0e, 0x69, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76,
-	0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x18, 0x0b, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x12, 0x1e, 0x0a,
-	0x0a, 0x62, 0x75, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0a, 0x62, 0x75, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x16, 0x0a,
-	0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75,
-	0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70,
-	0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70,
-	0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x0f, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x6b, 0x0a,
-	0x0d, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x19,
-	0x0a, 0x08, 0x65, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
-	0x52, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72,
-	0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x4d,
-	0x73, 0x67, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x12, 0x2e, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x2e, 0x42, 0x75, 0x79, 0x65, 0x72,
-	0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x49, 0x0a, 0x09, 0x42, 0x75,
-	0x79, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a,
-	0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x78,
-	0x62, 0x75, 0x79, 0x65, 0x72, 0x2e, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52,
-	0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0xbf, 0x01, 0x0a, 0x09, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c,
-	0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x05, 0x62, 0x75, 0x79, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x64,
-	0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65,
-	0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a,
-	0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x74,
-	0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x06, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x46,
-	0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69,
-	0x73, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x73, 0x52,
-	0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x73,
-	0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x32, 0x45, 0x0a, 0x07, 0x42, 0x78, 0x62, 0x75, 0x79,
-	0x65, 0x72, 0x12, 0x3a, 0x0a, 0x09, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12,
-	0x15, 0x2e, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x2e, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c,
-	0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72,
-	0x2e, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0b,
-	0x5a, 0x09, 0x2e, 0x2f, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x33,
+	0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x75, 0x79, 0x65, 0x72, 0x4e, 0x61,
+	0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x79, 0x65, 0x72, 0x4e,
+	0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x18,
+	0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x6e, 0x63, 0x65, 0x12,
+	0x12, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x63,
+	0x69, 0x74, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x53,
+	0x63, 0x6f, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x75, 0x73, 0x69,
+	0x6e, 0x65, 0x73, 0x73, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x72,
+	0x74, 0x52, 0x75, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x6f, 0x72,
+	0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b,
+	0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x73,
+	0x43, 0x68, 0x65, 0x63, 0x6b, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x12, 0x26, 0x0a, 0x0e, 0x69,
+	0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x18, 0x0a, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x63, 0x65,
+	0x69, 0x76, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x18,
+	0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x12,
+	0x1e, 0x0a, 0x0a, 0x62, 0x75, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x0c, 0x20,
+	0x03, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x75, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12,
+	0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54,
+	0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54,
+	0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18,
+	0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12,
+	0x14, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
+	0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72,
+	0x49, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65,
+	0x72, 0x49, 0x64, 0x22, 0x6b, 0x0a, 0x0d, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74,
+	0x52, 0x65, 0x73, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12,
+	0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72,
+	0x2e, 0x42, 0x75, 0x79, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61,
+	0x22, 0x49, 0x0a, 0x09, 0x42, 0x75, 0x79, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a,
+	0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f,
+	0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x12, 0x2e, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x2e, 0x42, 0x75, 0x79, 0x65,
+	0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0xc1, 0x01, 0x0a, 0x09,
+	0x42, 0x75, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x79,
+	0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x75, 0x79, 0x65, 0x72, 0x12,
+	0x16, 0x0a, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52,
+	0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69,
+	0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69,
+	0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x43, 0x6f, 0x75, 0x6e,
+	0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
+	0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x12,
+	0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x32,
+	0x45, 0x0a, 0x07, 0x42, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x09, 0x42, 0x75,
+	0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65,
+	0x72, 0x2e, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x16,
+	0x2e, 0x62, 0x78, 0x62, 0x75, 0x79, 0x65, 0x72, 0x2e, 0x42, 0x75, 0x79, 0x65, 0x72, 0x4c, 0x69,
+	0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x62, 0x78, 0x62, 0x75,
+	0x79, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (