wangshan пре 2 година
родитељ
комит
4bc825d845

+ 1 - 1
jyBXCore/go.mod

@@ -3,7 +3,7 @@ module jyBXCore
 go 1.16
 
 require (
-	app.yhyue.com/moapp/jybase v0.0.0-20230113085802-8e2760635a23
+	app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a
 	bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4
 	github.com/go-sql-driver/mysql v1.6.0
 	github.com/zeromicro/go-zero v1.4.0

+ 2 - 2
jyBXCore/go.sum

@@ -4,8 +4,8 @@ app.yhyue.com/moapp/jybase v0.0.0-20220415064050-37ce64b3e2d4/go.mod h1:qNRA0sHu
 app.yhyue.com/moapp/jybase v0.0.0-20220418104200-46c3fff161c7/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
 app.yhyue.com/moapp/jybase v0.0.0-20220420032112-668025915ee4/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
 app.yhyue.com/moapp/jybase v0.0.0-20220421060131-a1001013ba46/go.mod h1:qNRA0sHuYqcLoYoP8irpaWnW9YsXixe6obBIkwaXpD0=
-app.yhyue.com/moapp/jybase v0.0.0-20230113085802-8e2760635a23 h1:ttr6iVvpY7vLmiZlDyRPyFpP+tHWXnzQDbfRtcG3Vw8=
-app.yhyue.com/moapp/jybase v0.0.0-20230113085802-8e2760635a23/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
+app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a h1:wD4aWPSYdiX1cIP4lzzPD2s7fYhKa3muIf97l9tonJE=
+app.yhyue.com/moapp/jybase v0.0.0-20230117032034-ad7c00ffe11a/go.mod h1:zB47XTeJvpcbtBRYgkQuxOICWNexiZfbUO+7aUf6mNs=
 bp.jydev.jianyu360.cn/BP/jynsq v0.0.0-20220222052708-ebc43af90698/go.mod h1:ojo/AUH9Yr1wzarEjOaNMkj1Cet/9r8IgLyba64Z52E=
 bp.jydev.jianyu360.cn/BaseService/gateway v0.0.0-20220419090715-88ddb32961be/go.mod h1:Yj4oabIGItuMoF0BXYLz2XAnF581kxgXBrvlUtIJrkI=
 bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4 h1:zl5eZrKDBENVVBUiPpzyQQ0/SBdGUmZS3thXycSEO1g=

+ 16 - 11
jyBXCore/rpc/bxcore.proto

@@ -32,7 +32,7 @@ message SearchReq {
   string exclusionWords = 26;//关键词:排除词(副:五组,每组最多15个字符)
   string  userType = 27;//用户状态 fType:免费用户;pType:付费用户;vType:超级订阅用户;mType:大会员用户;eType:商机管理用户
   string  platform = 28;//请求平台
-  bool  isFree = 29;//是否是免费用户
+  bool  isPay = 29;//是否是付费用户
   string interceptKeyWords = 30;//关键词截取后的关键词;
   string interceptOtherWords = 31;//关键词截取后 后面三个字
 }
@@ -63,7 +63,7 @@ message  SearchList {
   string detail = 6;//正文搜索内容
   string industry = 7;//行业标签
   string industryUrl = 8;//行业标签地址
-  int64  publishTime = 9;//发布时间
+  string  publishTime = 9;//发布时间
   bool   fileExists = 10;//是否有附件
   string subtype = 11;//信息类型
   string subtypeUrl = 12;//信息类型标签地址
@@ -79,15 +79,20 @@ message  SearchList {
   string agency = 22;//代理机构
   string agencyPerson = 23;//代理机构联系人
   string agencyTel = 24;//代理机构联系电话
-  string winner = 25;//中标企业
-  string winnerPerson = 26;//中标企业联系人
-  string winnerTel = 27;//中标企业联系电话
-  string bidOpenTime = 28;//开标时间
-  string signEndTime = 29;//报名截止时间
-  string bidEndTime = 30;//投标截止时间
-  string site = 31;//网站名称
-  string spiderCode = 32;//网站代码
-  PInfo  projectInfo = 33;//拟建项目信息
+  repeated WinnerInfo winnerInfo = 25;//中标企业信息
+  string bidOpenTime = 26;//开标时间
+  string signEndTime = 27;//报名截止时间
+  string bidEndTime = 28;//投标截止时间
+  string site = 29;//网站名称
+  string spiderCode = 30;//网站代码
+  PInfo  projectInfo = 31;//拟建项目信息
+}
+//
+message WinnerInfo{
+  string winner = 1;
+  string winnerTel = 2;
+  string winnerPerson = 3;
+  string winnerId = 4;
 }
 //
 message PInfo {

+ 53 - 20
jyBXCore/rpc/entity/search.go

@@ -15,8 +15,8 @@ import (
 )
 
 var (
-	SearchCacheKey   = "searchDataCache_%s"
-	SearchCacheCount = "searchCountCache_%s"
+	SearchCacheKey   = "searchDataCache_%s_%s"
+	SearchCacheCount = "searchCountCache_%s_%s"
 )
 
 type KeyWordsSearch struct{}
@@ -34,17 +34,18 @@ func (kws *KeyWordsSearch) IsEmptySearch(in *bxcore.SearchReq) bool {
 	return true
 }
 
-// GetBidListByCache  查询缓存数据
-func (kws *KeyWordsSearch) GetBidListByCache(in *bxcore.SearchReq) (list []*bxcore.SearchList, count int64) {
-	//缓存数据 最大量是500条  十页数据
+// GetBidSearchListByCache   查询缓存数据
+//未登录用户默认搜索和关键词搜索改成500条和免费用户保持一致--需求调整P260来自产品经理杨蘭20220116
+func (kws *KeyWordsSearch) GetBidSearchListByCache(in *bxcore.SearchReq) (list []*bxcore.SearchList, count int64) {
+	//缓存数据 最大量是5000条  100页数据
 	l, c := func(in *bxcore.SearchReq) (list []*bxcore.SearchList, count int64) {
-		//缓存数据: kws.Platform-平台;kws.PageNum-当前页
-		redisDataKey := fmt.Sprintf(SearchCacheKey, in.Platform)
+		//缓存数据: kws.Platform-平台;kws.PageNum-当前页 免费用户 or 付费用户
+		redisDataKey := fmt.Sprintf(SearchCacheKey, in.Platform, MC.If(in.IsPay, "V", "F").(string))
 		//缓存数据总量 - 当前平台
-		redisCountKey := fmt.Sprintf(SearchCacheCount, in.Platform)
-		sCache, err := redis.GetNewBytes(util.RedisName, redisDataKey)
+		redisCountKey := fmt.Sprintf(SearchCacheCount, in.Platform, MC.If(in.IsPay, "V", "F").(string))
+		sCache, err := redis.GetNewBytes(util.RedisNameNew, redisDataKey)
+		count = int64(redis.GetInt(util.RedisNameNew, redisCountKey))
 		if err == nil {
-			count = int64(redis.GetInt(util.RedisName, redisCountKey))
 			if sCache != nil && len(*sCache) > 0 {
 				err = json.Unmarshal(*sCache, &list)
 				if err == nil {
@@ -54,21 +55,19 @@ func (kws *KeyWordsSearch) GetBidListByCache(in *bxcore.SearchReq) (list []*bxco
 		}
 		//无缓存数据 或 缓存数据查询异常
 		//查库>存redis缓存
-		//缓存数据 默认查询分组 searchGroup = 1 ,
-		//不查超前信息--招标信息类型为拟建和采购意向的信息
-		in.SearchGroup = 1
-		in.Subtype = IC.C.DefaultTopTypes[in.SearchGroup]
+		//查询缓存数据 参数初始化
+		kws.DefaultSearchParamsAuto(in)
 		//缓存数据
 		count, list = service.SearchCacheData(in)
-		limitCount := int64(util.SearchPageSize * util.SearchMaxPageNum)
+		limitCount := int64(util.SearchPageSize * MC.If(in.IsPay, util.SearchMaxPageNum_PAYED, util.SearchMaxPageNum).(int))
 		if count > limitCount {
 			count = limitCount
 		}
 		if len(list) > 0 {
-			redis.Put(util.RedisName, redisCountKey, count, MC.If(IC.C.DefaultSearchCacheTime > 0, IC.C.DefaultSearchCacheTime*60*60, 24*60*60).(int))
+			redis.Put(util.RedisNameNew, redisCountKey, count, MC.If(IC.C.DefaultSearchCacheTime > 0, IC.C.DefaultSearchCacheTime*60*60, 24*60*60).(int))
 			b, err := json.Marshal(list)
 			if err == nil {
-				redis.PutBytes(util.RedisName, redisDataKey, &b, MC.If(IC.C.DefaultSearchCacheTime > 0, IC.C.DefaultSearchCacheTime*60*60, 24*60*60).(int))
+				redis.PutBytes(util.RedisNameNew, redisDataKey, &b, MC.If(IC.C.DefaultSearchCacheTime > 0, IC.C.DefaultSearchCacheTime*60*60, 24*60*60).(int))
 			} else {
 				logx.Info("默认搜索查询结果保存redis缓存异常")
 			}
@@ -87,6 +86,25 @@ func (kws *KeyWordsSearch) GetBidListByCache(in *bxcore.SearchReq) (list []*bxco
 	return
 }
 
+//缓存查询条件初始化
+func (kws *KeyWordsSearch) DefaultSearchParamsAuto(in *bxcore.SearchReq) {
+	//缓存数据 默认查询分组 searchGroup = 1 ,
+	//不查超前信息--招标信息类型为拟建和采购意向的信息
+	in.SearchGroup = 1
+	in.Subtype = IC.C.DefaultTopTypes[in.SearchGroup]
+	in.TopType = ""
+	in.City = ""
+	in.Industry = ""
+	in.FileExists = ""
+	in.WinnerTel = ""
+	in.BuyerTel = ""
+	in.BuyerClass = ""
+	in.Price = ""
+	in.SelectType = "title"
+	in.PublishTime = ""
+	in.Province = ""
+}
+
 // SaveKeyWordsToHistory 保存历史记录
 func (kws *KeyWordsSearch) SaveKeyWordsToHistory(in *bxcore.SearchReq) {
 	if in.KeyWords != "" {
@@ -101,7 +119,7 @@ func (kws *KeyWordsSearch) SaveKeyWordsToHistory(in *bxcore.SearchReq) {
 	}
 }
 
-//搜索条件 处理
+// SearchParamsHandle 搜索条件 处理
 func (kws *KeyWordsSearch) SearchParamsHandle(in *bxcore.SearchReq) {
 	//默认每页数据量
 	if in.PageSize == 0 {
@@ -134,10 +152,25 @@ func (kws *KeyWordsSearch) SearchParamsHandle(in *bxcore.SearchReq) {
 	}
 	//判断用户身份
 	userInfo := util.GetVipState(IC.MainMysql, IC.Mgo, in.UserId)
-	//是否是费用户
-	in.IsFree = !userInfo.IsPayedUser()
+	//是否是费用户
+	in.IsPay = userInfo.IsPayedUser()
 	//搜索范围
 	queryItems := userInfo.GetQueryItems(in.SelectType, IC.C.BidSearchOldUserLimit)
 	in.SelectType = strings.Join(queryItems, ",")
+}
 
+// GetBidSearchList 非空搜索 查询
+func (kws *KeyWordsSearch) GetBidSearchList(in *bxcore.SearchReq) (count int64, list []*bxcore.SearchList, numberMsg string) {
+	var start = int((in.PageNum - 1) * in.PageSize)
+	//排除异常in.PageNum参数
+	if start >= 0 {
+		count, list = service.GetBidSearchData(in)
+		util.MakeCollection(in.UserId, list)
+		numberMsg = fmt.Sprintf("%d", count) //返回数据总量提示信息
+		limitCount := MC.If(in.IsPay, int64(util.SearchPageSize*util.SearchMaxPageNum_PAYED), int64(util.SearchPageSize*util.SearchMaxPageNum)).(int64)
+		if count > limitCount {
+			count = limitCount //付费用户count 最多5000条,100页数据,每页50条;免费用户count 最多500条,10页数据,每页50条。
+		}
+	}
+	return
 }

+ 2 - 1
jyBXCore/rpc/etc/bxcore.yaml

@@ -35,7 +35,8 @@ KeywordsLimit: 35 #主搜索框 关键词长度限制
 DefaultBidInfo: #默认搜索
   NumMsg: 超过1.8亿 #数据量提示
   PageNum: 10 #总页数
-  Count: 1000 #查询数据量
+  Count: 500 #查询数据量
+  PayCount: 5000 #付费用户查询数据量
 DefaultTopTypes:
   - 拟建,采购意向,招标预告,招标公告,招标结果,招标信用信息
   - 招标预告,招标公告,招标结果,招标信用信息

+ 1 - 0
jyBXCore/rpc/etc/db.yaml

@@ -9,6 +9,7 @@ mysql:
 redis:
     addr:
         - other=192.168.3.206:1712
+        - newother=192.168.3.206:1712
 es:
     addr: http://192.168.3.206:9800
     size: 50

+ 4 - 3
jyBXCore/rpc/internal/config/config.go

@@ -36,9 +36,10 @@ type Config struct {
 	}
 	KeywordsLimit  int
 	DefaultBidInfo struct {
-		NumMsg  string
-		PageNum int
-		Count   int
+		NumMsg   string
+		PageNum  int
+		Count    int
+		PayCount int
 	}
 	DefaultTopTypes []string
 }

+ 10 - 18
jyBXCore/rpc/internal/logic/getsearchlistlogic.go

@@ -51,22 +51,22 @@ func (l *GetSearchListLogic) GetSearchList(in *bxcore.SearchReq) (*bxcore.Search
 	ks.SearchParamsHandle(in)
 	//判断是否是空搜索,如果是空搜索,查缓存数据
 	if ks.IsEmptySearch(in) {
-		res.List, res.Count = ks.GetBidListByCache(in)
+		res.List, res.Count = ks.GetBidSearchListByCache(in)
 		return &bxcore.SearchResp{
 			Data:    res,
 			ErrMsg:  "",
 			ErrCode: 0,
 		}, nil
 	}
-	//异常付费用户
-	if in.UserType != "fType" && !in.IsFree {
+	//异常付费用户  参数不是免费fType,但是又不是付费用户;还有一种是未登录用户 稍后处理
+	if in.UserType != "fType" && !in.IsPay {
 		return &bxcore.SearchResp{
 			ErrCode: -1,
 			ErrMsg:  "无权限",
 		}, nil
 	}
-	//招标信息有效查询
 	t := time.Now()
+	//招标信息有效查询
 	res.IsLimit = 1
 	//查询数据
 	searchLimit := util.IsSearchLimit(strings.Split(in.SelectType, ","))
@@ -79,32 +79,24 @@ func (l *GetSearchListLogic) GetSearchList(in *bxcore.SearchReq) (*bxcore.Search
 	}
 	//无限制
 	if res.IsLimit == 1 {
-		//付费用户搜索优化
+		//付费用户搜索优化--默认搜索5年数据,数据量太多,接口反应太慢,前两页数据 时间范围根据配置缩小查询以达到快速查询的目的。
 		publishTime := in.PublishTime
 		t1 := time.Now()
 		if b := util.IsOptimize(IC.C, in); b {
-			res.Count, res.List = util.GetBidSearchData(in)
-			res.Count += 1 //避免刚好50条 无法加载下一页数据
+			res.Count, res.List, res.NumberMsg = ks.GetBidSearchList(in) // util.GetBidSearchData(in)
+			//res.Count += 1 //移动端:避免刚好50条 无法加载下一页数据//直接返回数据总量
 		}
 		logx.Info("1查询耗时", time.Since(t1))
 		t2 := time.Now()
-		//不够配置条 走原始查询
+		//如果优化查询数据量提少,和配置数据量作比较,不够的话走原始查询
 		if res.Count < IC.C.PaySearchLimit.PageSize {
 			in.PublishTime = publishTime
-			res.Count, res.List = util.GetBidSearchData(in)
+			res.Count, res.List, res.NumberMsg = ks.GetBidSearchList(in) //util.GetBidSearchData(in)
 		}
 		logx.Info("2查询耗时:", time.Since(t2))
-		limitCount := MC.If(in.UserType != "fType", int64(util.SearchPageSize*util.SearchMaxPageNum_PAYED), int64(util.SearchPageSize*util.SearchMaxPageNum)).(int64)
-		if res.Count > limitCount {
-			res.Count = limitCount
-		}
+
 		res.KeyWords = in.KeyWords
 		res.InterceptOtherWords = in.InterceptOtherWords
-		//是否收藏
-		//util.MakeCollection(in.UserId, list)
-		//res.TotalPage = MC.If(in.PageNum == 1, (count+int64(util.SearchPageSize)-1)/int64(util.SearchPageSize), res.TotalPage).(int64)
-		//res.Count = count
-		//res.List = list
 	}
 	logx.Info("关键词 -全部- 查询耗时:", time.Since(t).Seconds())
 	return &bxcore.SearchResp{

+ 19 - 11
jyBXCore/rpc/model/es/es.go

@@ -12,13 +12,20 @@ const (
 	HL           = `"highlight": {"pre_tags": [""],"post_tags": [""],"fields": {%s}}`
 	INDEX        = "bidding"
 	TYPE         = "bidding"
+
+	BidSearchSort       = `{"dataweight":-1,"publishtime":-1}`
+	BidSearchFieldBase  = `"_id","title","publishtime","dataweight","toptype","subtype","type","area","city","s_subscopeclass","bidamount","budget","buyerclass","spidercode","site"`                                                    //搜索列表基础字段
+	BidSearchFieldOfVip = BidSearchFieldBase + `,"buyer","buyertel","buyerperson","agency","agencytel","agencyperson","s_winner","winnertel","winnerperson","signendtime","bidendtime","bidopentime","budget","projectinfo","entidlist"` //付费列表字段
+	BidSearchFieldFile  = `,"isValidFile"`                                                                                                                                                                                               //根据配置开关 选择是否显示 是否有附件提示,IC.C.FileSignBool
+
+	DefaultFields = `"title"` //最新招标信息
 )
 
 var SR = strings.Replace
 
-type EsSearch struct {
+type ESSearch struct {
 	Index      string
-	Itype      string
+	IType      string
 	Query      string
 	FindFields string
 	Order      string
@@ -29,27 +36,28 @@ type EsSearch struct {
 	HighLight  bool
 }
 
-//
-func (e *EsSearch) GetAllByNgramWithCount() (int64, *[]map[string]interface{}) {
-	qstr := e.Query
+// GetAllByNgramWithCount  获取es查询结果及总数量
+func (e *ESSearch) GetAllByNgramWithCount() (int64, *[]map[string]interface{}) {
 	if e.Query != "" {
+		queryStr := e.Query
 		if e.HighLight {
-			ws := []string{}
+			var ws []string
 			for _, w := range strings.Split(e.FindFields, ",") {
 				ws = append(ws, fmt.Sprintf(highlightStr, w, e.Count))
 			}
-			qstr = qstr[:len(qstr)-1] + `,` + fmt.Sprintf(HL, strings.Join(ws, ",")) + `}`
+			queryStr = queryStr[:len(queryStr)-1] + `,` + fmt.Sprintf(HL, strings.Join(ws, ",")) + `}`
 		}
 		if len(e.Fields) > 0 {
-			qstr = qstr[:len(qstr)-1] + `,"_source":[` + e.Fields + "]}"
+			queryStr = queryStr[:len(queryStr)-1] + `,"_source":[` + e.Fields + "]}"
 		}
 		if len(e.Order) > 0 {
-			qstr = qstr[:len(qstr)-1] + `,"sort":[` + SR(SR(SR(SR(e.Order, ",", "},{", -1), " ", "", -1), ":-1", `:"desc"`, -1), ":1", `:"asc"`, -1) + `]}`
+			queryStr = queryStr[:len(queryStr)-1] + `,"sort":[` + SR(SR(SR(SR(e.Order, ",", "},{", -1), " ", "", -1), ":-1", `:"desc"`, -1), ":1", `:"asc"`, -1) + `]}`
 		}
 		if e.Start > -1 {
-			qstr = qstr[:len(qstr)-1] + `,"from":` + strconv.Itoa(e.Start) + `,"size":` + strconv.Itoa(e.Limit) + "}"
+			queryStr = queryStr[:len(queryStr)-1] + `,"from":` + strconv.Itoa(e.Start) + `,"size":` + strconv.Itoa(e.Limit) + "}"
 		}
-		return elastic.GetWithCount(e.Index, e.Itype, qstr)
+		//logx.Info("queryStr:", queryStr)
+		return elastic.GetWithCount(e.Index, e.IType, queryStr)
 	} else {
 		return 0, nil
 	}

+ 5 - 7
jyBXCore/rpc/model/es/search.go

@@ -17,12 +17,10 @@ func GetSearchCacheData(query string) (*[]map[string]interface{}, int64) {
 
 }
 
-//
+// GetSearchQuery  整理关键词等查询条件
 func GetSearchQuery(in *bxcore.SearchReq, mustquery string) (qstr string) {
 	multi_match := `{"multi_match": {"query": "%s","type": "phrase", "fields": [%s]}}`
 	query := `{"query":{"bool":{"must":[%s],"must_not":[%s]}}}`
-	//query := `{"query": {"function_score": {"query": {"bool": {"must": [%s],"must_not": [%s]}},"field_value_factor": {"field": "dataweight","modifier": "ln1p","missing": 0}}}}`
-
 	query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
 	query_bools_must := `{"bool":{"must":[{"range":{"bidamount":{%s}}}]}},{"bool":{"must":[{"range":{"budget":{%s}}}],"must_not":[{"range":{"bidamount":{"gte":-1}}}]}}`
 	query_bool_must := `{"bool":{"must":[{"terms":{"s_subscopeclass":[%s]}}]}}`
@@ -162,7 +160,7 @@ func GetSearchQuery(in *bxcore.SearchReq, mustquery string) (qstr string) {
 	return
 }
 
-//
+// GetBidSearchQuery  整理地区、城市、发布时间、信息类型、采购单位类型 查询条件
 func GetBidSearchQuery(in *bxcore.SearchReq) string {
 	query := ``
 	//省份
@@ -276,7 +274,7 @@ func GetBidSearchQuery(in *bxcore.SearchReq) string {
 	return query
 }
 
-//包含正文或 附件 不包含标题
-func DetailFileORTitle(findfields string) bool {
-	return (strings.Contains(findfields, `"detail"`) || strings.Contains(findfields, `"filetext"`)) && !strings.Contains(findfields, `"title"`)
+// DetailFileORTitle 包含正文或 附件 不包含标题
+func DetailFileORTitle(findFields string) bool {
+	return (strings.Contains(findFields, `"detail"`) || strings.Contains(findFields, `"filetext"`)) && !strings.Contains(findFields, `"title"`)
 }

+ 0 - 6
jyBXCore/rpc/model/es/searchQuery.go

@@ -18,12 +18,6 @@ const (
 	bidSearch_sort    = `{"dataweight":-1,"publishtime":-1}`
 	bidSearch_field_1 = `"_id","title","publishtime","dataweight","toptype","subtype","type","area","city","s_subscopeclass","bidamount","budget","buyerclass","spidercode","site"` //,"filetext"
 	bidSearch_field   = bidSearch_field_1 + `,"bidopentime","winner","buyer","projectname","projectcode","projectinfo"`
-
-	bidSearchFieldBase  = `"_id","title","publishtime","dataweight","toptype","subtype","type","area","city","s_subscopeclass","bidamount","budget","buyerclass","spidercode","site"` //搜索列表基础字段
-	bidSearchFieldOfVip = `"buyer","agency","s_winner","buyertel","winnertel","agencytel","signendtime","bidendtime","bidopentime","budget","bidamount","projectinfo"`                //付费列表字段
-	bidSearchFieldFile  = `,"isValidFile"`                                                                                                                                            //根据配置开关 选择是否显示 是否有附件提示,IC.C.FileSignBool
-
-	DefaultFields = `"title"` //最新招标信息
 )
 
 //

+ 53 - 43
jyBXCore/rpc/service/search.go

@@ -1,58 +1,68 @@
 package service
 
 import (
+	MC "app.yhyue.com/moapp/jybase/common"
 	"github.com/zeromicro/go-zero/core/logx"
 	"jyBXCore/rpc/bxcore"
+	IC "jyBXCore/rpc/init"
 	"jyBXCore/rpc/model/es"
 	"jyBXCore/rpc/util"
+	"strings"
+	"time"
 )
 
-// SearchCacheData  默认查询缓存数据
-// 默认搜索1000条数据,从搜索结果随机获取500条数据
+// SearchCacheData  默认查询缓存数据 只查标题
+// 登录用户默认搜索500条数据,付费用户字段和免费用户字段不同,未登录用户查询5000条
 func SearchCacheData(in *bxcore.SearchReq) (count int64, list []*bxcore.SearchList) {
-	resList, _ := es.GetSearchCacheData(es.GetSearchQuery(in, es.GetBidSearchQuery(in)))
-	if resList != nil && len(*resList) > 0 {
-		*resList = append((*resList)[1:444], (*resList)[666:888]...)
-		//数据>500 ,从len(*resList)中随机抽取500
-		pageSize := int(in.PageSize)
-		if len(*resList) > pageSize*10 {
-			var (
-				ll        = len(*resList) / pageSize //数据分50等份
-				formatArr = make([][]map[string]interface{}, ll)
-			)
-			//插入二维数组
-			for i := 0; i < ll; i++ {
-				start := i * pageSize
-				end := (i + 1) * pageSize
-				if i == ll-1 {
-					end = len(*resList)
-				}
-				formatArr[i] = make([]map[string]interface{}, len((*resList)[start:end]))
-				formatArr[i] = (*resList)[start:end]
-			}
-			//判断二维码数组是否有值
-			if len(formatArr) > 0 {
-				//最后一个数组是否满整页数据(50)
-				if len(formatArr[ll-1]) != pageSize {
-					//不满50 抛弃
-					ll = ll - 1
-				}
-			}
-			//当前数据量 正常肯定能查到1000条
-			if ll > 10 {
-				*resList = []map[string]interface{}{}
-				for j := 0; j < ll; j++ {
-					if j%2 == 0 {
-						*resList = append(*resList, formatArr[j]...)
-					}
-				}
-			}
-		}
-		util.BidListConvert(in.Industry, resList)
-		list = util.SearchListFormart(resList, false)
-		count = int64(len(list))
+	t := time.Now()
+	query := MC.If(in.IsPay, es.BidSearchFieldOfVip, es.BidSearchFieldBase).(string)
+	biddingSearch := es.ESSearch{
+		Index:      es.INDEX,
+		IType:      es.TYPE,
+		Query:      es.GetSearchQuery(in, es.GetBidSearchQuery(in)),
+		FindFields: "title",
+		Order:      es.BidSearchSort,
+		Fields:     MC.If(IC.C.FileSignBool, query+es.BidSearchFieldFile, query).(string), //IC.C.FileSignBool列表是否显示附件开关
+		Start:      0,
+		Limit:      MC.If(in.IsPay, IC.C.DefaultBidInfo.PayCount, IC.C.DefaultBidInfo.Count).(int), //付费用户5000条,免费用户及未登录500条
+		Count:      MC.If(strings.Contains(in.SelectType, "detail"), 115, 0).(int),                 //高亮正文数量
+		HighLight:  MC.If(strings.Contains(in.SelectType, "detail"), true, false).(bool),           //是否高亮正文
+	}
+	var repl *[]map[string]interface{}
+	count, repl = biddingSearch.GetAllByNgramWithCount()
+	if repl != nil && *repl != nil && len(*repl) > 0 {
+		list = util.SearchListFormat(in.Industry, repl, false)
 	} else {
 		logx.Info("查询缓存异常")
 	}
+	logx.Info("关键词 -cache- 查询耗时:", time.Since(t).Seconds())
+	return
+}
+
+//GetBidSearchData 标信息搜索
+func GetBidSearchData(in *bxcore.SearchReq) (count int64, list []*bxcore.SearchList) {
+	var start = int((in.PageNum - 1) * in.PageSize)
+	if start >= 0 {
+		t := time.Now()
+		biddingSearch := es.ESSearch{
+			Index:      es.INDEX,
+			IType:      es.TYPE,
+			Query:      es.GetSearchQuery(in, es.GetBidSearchQuery(in)),
+			FindFields: "detail",
+			Order:      es.BidSearchSort,
+			Fields:     MC.If(IC.C.FileSignBool, MC.If(in.IsPay, es.BidSearchFieldOfVip, es.BidSearchFieldBase).(string)+es.BidSearchFieldFile, MC.If(in.IsPay, es.BidSearchFieldOfVip, es.BidSearchFieldBase).(string)).(string), //IC.C.FileSignBool列表是否显示附件开关
+			Start:      start,
+			Limit:      int(in.PageSize),
+			Count:      MC.If(strings.Contains(in.SelectType, "detail"), 115, 0).(int), //高亮正文数量
+			HighLight:  MC.If(strings.Contains(in.SelectType, "detail"), 1, 0).(bool),  //是否高亮正文
+		}
+		var repl *[]map[string]interface{}
+		count, repl = biddingSearch.GetAllByNgramWithCount()
+		if repl != nil && *repl != nil && len(*repl) > 0 {
+			//格式化查询结果
+			list = util.SearchListFormat(in.Industry, repl, true)
+		}
+		logx.Info("关键词 -1- 查询耗时:", time.Since(t).Seconds())
+	}
 	return
 }

+ 297 - 222
jyBXCore/rpc/type/bxcore/bxcore.pb.go

@@ -53,7 +53,7 @@ type SearchReq struct {
 	ExclusionWords      string `protobuf:"bytes,26,opt,name=exclusionWords,proto3" json:"exclusionWords,omitempty"`           //关键词:排除词(副:五组,每组最多15个字符)
 	UserType            string `protobuf:"bytes,27,opt,name=userType,proto3" json:"userType,omitempty"`                       //用户状态 fType:免费用户;pType:付费用户;vType:超级订阅用户;mType:大会员用户;eType:商机管理用户
 	Platform            string `protobuf:"bytes,28,opt,name=platform,proto3" json:"platform,omitempty"`                       //请求平台
-	IsFree              bool   `protobuf:"varint,29,opt,name=isFree,proto3" json:"isFree,omitempty"`                          //是否是免费用户
+	IsPay               bool   `protobuf:"varint,29,opt,name=isPay,proto3" json:"isPay,omitempty"`                            //是否是付费用户
 	InterceptKeyWords   string `protobuf:"bytes,30,opt,name=interceptKeyWords,proto3" json:"interceptKeyWords,omitempty"`     //关键词截取后的关键词;
 	InterceptOtherWords string `protobuf:"bytes,31,opt,name=interceptOtherWords,proto3" json:"interceptOtherWords,omitempty"` //关键词截取后 后面三个字
 }
@@ -286,9 +286,9 @@ func (x *SearchReq) GetPlatform() string {
 	return ""
 }
 
-func (x *SearchReq) GetIsFree() bool {
+func (x *SearchReq) GetIsPay() bool {
 	if x != nil {
-		return x.IsFree
+		return x.IsPay
 	}
 	return false
 }
@@ -486,39 +486,37 @@ type SearchList struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Id           string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`                      //信息id
-	Area         string `protobuf:"bytes,2,opt,name=area,proto3" json:"area,omitempty"`                  //地区
-	AreaUrl      string `protobuf:"bytes,3,opt,name=areaUrl,proto3" json:"areaUrl,omitempty"`            //地区标签地址
-	BuyerClass   string `protobuf:"bytes,4,opt,name=buyerClass,proto3" json:"buyerClass,omitempty"`      //采购单位类型
-	City         string `protobuf:"bytes,5,opt,name=city,proto3" json:"city,omitempty"`                  //城市
-	Detail       string `protobuf:"bytes,6,opt,name=detail,proto3" json:"detail,omitempty"`              //正文搜索内容
-	Industry     string `protobuf:"bytes,7,opt,name=industry,proto3" json:"industry,omitempty"`          //行业标签
-	IndustryUrl  string `protobuf:"bytes,8,opt,name=industryUrl,proto3" json:"industryUrl,omitempty"`    //行业标签地址
-	PublishTime  int64  `protobuf:"varint,9,opt,name=publishTime,proto3" json:"publishTime,omitempty"`   //发布时间
-	FileExists   bool   `protobuf:"varint,10,opt,name=fileExists,proto3" json:"fileExists,omitempty"`    //是否有附件
-	Subtype      string `protobuf:"bytes,11,opt,name=subtype,proto3" json:"subtype,omitempty"`           //信息类型
-	SubtypeUrl   string `protobuf:"bytes,12,opt,name=subtypeUrl,proto3" json:"subtypeUrl,omitempty"`     //信息类型标签地址
-	Title        string `protobuf:"bytes,13,opt,name=title,proto3" json:"title,omitempty"`               //标题
-	IsCollected  bool   `protobuf:"varint,14,opt,name=isCollected,proto3" json:"isCollected,omitempty"`  //信息是否被收藏
-	ProjectName  string `protobuf:"bytes,15,opt,name=projectName,proto3" json:"projectName,omitempty"`   //项目名称
-	ProjectCode  string `protobuf:"bytes,16,opt,name=projectCode,proto3" json:"projectCode,omitempty"`   //项目代码
-	Budget       int64  `protobuf:"varint,17,opt,name=budget,proto3" json:"budget,omitempty"`            //预算
-	BidAmount    int64  `protobuf:"varint,18,opt,name=bidAmount,proto3" json:"bidAmount,omitempty"`      //中标金额
-	Buyer        string `protobuf:"bytes,19,opt,name=buyer,proto3" json:"buyer,omitempty"`               //采购单位
-	BuyerTel     string `protobuf:"bytes,20,opt,name=buyerTel,proto3" json:"buyerTel,omitempty"`         //采购单位联系电话
-	BuyerPerson  string `protobuf:"bytes,21,opt,name=buyerPerson,proto3" json:"buyerPerson,omitempty"`   //采购单位联系人
-	Agency       string `protobuf:"bytes,22,opt,name=agency,proto3" json:"agency,omitempty"`             //代理机构
-	AgencyPerson string `protobuf:"bytes,23,opt,name=agencyPerson,proto3" json:"agencyPerson,omitempty"` //代理机构联系人
-	AgencyTel    string `protobuf:"bytes,24,opt,name=agencyTel,proto3" json:"agencyTel,omitempty"`       //代理机构联系电话
-	Winner       string `protobuf:"bytes,25,opt,name=winner,proto3" json:"winner,omitempty"`             //中标企业
-	WinnerPerson string `protobuf:"bytes,26,opt,name=winnerPerson,proto3" json:"winnerPerson,omitempty"` //中标企业联系人
-	WinnerTel    string `protobuf:"bytes,27,opt,name=winnerTel,proto3" json:"winnerTel,omitempty"`       //中标企业联系电话
-	BidOpenTime  string `protobuf:"bytes,28,opt,name=bidOpenTime,proto3" json:"bidOpenTime,omitempty"`   //开标时间
-	SignEndTime  string `protobuf:"bytes,29,opt,name=signEndTime,proto3" json:"signEndTime,omitempty"`   //报名截止时间
-	BidEndTime   string `protobuf:"bytes,30,opt,name=bidEndTime,proto3" json:"bidEndTime,omitempty"`     //投标截止时间
-	Site         string `protobuf:"bytes,31,opt,name=site,proto3" json:"site,omitempty"`                 //网站名称
-	SpiderCode   string `protobuf:"bytes,32,opt,name=spiderCode,proto3" json:"spiderCode,omitempty"`     //网站代码
-	ProjectInfo  *PInfo `protobuf:"bytes,33,opt,name=projectInfo,proto3" json:"projectInfo,omitempty"`   //拟建项目信息
+	Id           string        `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`                      //信息id
+	Area         string        `protobuf:"bytes,2,opt,name=area,proto3" json:"area,omitempty"`                  //地区
+	AreaUrl      string        `protobuf:"bytes,3,opt,name=areaUrl,proto3" json:"areaUrl,omitempty"`            //地区标签地址
+	BuyerClass   string        `protobuf:"bytes,4,opt,name=buyerClass,proto3" json:"buyerClass,omitempty"`      //采购单位类型
+	City         string        `protobuf:"bytes,5,opt,name=city,proto3" json:"city,omitempty"`                  //城市
+	Detail       string        `protobuf:"bytes,6,opt,name=detail,proto3" json:"detail,omitempty"`              //正文搜索内容
+	Industry     string        `protobuf:"bytes,7,opt,name=industry,proto3" json:"industry,omitempty"`          //行业标签
+	IndustryUrl  string        `protobuf:"bytes,8,opt,name=industryUrl,proto3" json:"industryUrl,omitempty"`    //行业标签地址
+	PublishTime  string        `protobuf:"bytes,9,opt,name=publishTime,proto3" json:"publishTime,omitempty"`    //发布时间
+	FileExists   bool          `protobuf:"varint,10,opt,name=fileExists,proto3" json:"fileExists,omitempty"`    //是否有附件
+	Subtype      string        `protobuf:"bytes,11,opt,name=subtype,proto3" json:"subtype,omitempty"`           //信息类型
+	SubtypeUrl   string        `protobuf:"bytes,12,opt,name=subtypeUrl,proto3" json:"subtypeUrl,omitempty"`     //信息类型标签地址
+	Title        string        `protobuf:"bytes,13,opt,name=title,proto3" json:"title,omitempty"`               //标题
+	IsCollected  bool          `protobuf:"varint,14,opt,name=isCollected,proto3" json:"isCollected,omitempty"`  //信息是否被收藏
+	ProjectName  string        `protobuf:"bytes,15,opt,name=projectName,proto3" json:"projectName,omitempty"`   //项目名称
+	ProjectCode  string        `protobuf:"bytes,16,opt,name=projectCode,proto3" json:"projectCode,omitempty"`   //项目代码
+	Budget       int64         `protobuf:"varint,17,opt,name=budget,proto3" json:"budget,omitempty"`            //预算
+	BidAmount    int64         `protobuf:"varint,18,opt,name=bidAmount,proto3" json:"bidAmount,omitempty"`      //中标金额
+	Buyer        string        `protobuf:"bytes,19,opt,name=buyer,proto3" json:"buyer,omitempty"`               //采购单位
+	BuyerTel     string        `protobuf:"bytes,20,opt,name=buyerTel,proto3" json:"buyerTel,omitempty"`         //采购单位联系电话
+	BuyerPerson  string        `protobuf:"bytes,21,opt,name=buyerPerson,proto3" json:"buyerPerson,omitempty"`   //采购单位联系人
+	Agency       string        `protobuf:"bytes,22,opt,name=agency,proto3" json:"agency,omitempty"`             //代理机构
+	AgencyPerson string        `protobuf:"bytes,23,opt,name=agencyPerson,proto3" json:"agencyPerson,omitempty"` //代理机构联系人
+	AgencyTel    string        `protobuf:"bytes,24,opt,name=agencyTel,proto3" json:"agencyTel,omitempty"`       //代理机构联系电话
+	WinnerInfo   []*WinnerInfo `protobuf:"bytes,25,rep,name=winnerInfo,proto3" json:"winnerInfo,omitempty"`     //中标企业信息
+	BidOpenTime  string        `protobuf:"bytes,26,opt,name=bidOpenTime,proto3" json:"bidOpenTime,omitempty"`   //开标时间
+	SignEndTime  string        `protobuf:"bytes,27,opt,name=signEndTime,proto3" json:"signEndTime,omitempty"`   //报名截止时间
+	BidEndTime   string        `protobuf:"bytes,28,opt,name=bidEndTime,proto3" json:"bidEndTime,omitempty"`     //投标截止时间
+	Site         string        `protobuf:"bytes,29,opt,name=site,proto3" json:"site,omitempty"`                 //网站名称
+	SpiderCode   string        `protobuf:"bytes,30,opt,name=spiderCode,proto3" json:"spiderCode,omitempty"`     //网站代码
+	ProjectInfo  *PInfo        `protobuf:"bytes,31,opt,name=projectInfo,proto3" json:"projectInfo,omitempty"`   //拟建项目信息
 }
 
 func (x *SearchList) Reset() {
@@ -609,11 +607,11 @@ func (x *SearchList) GetIndustryUrl() string {
 	return ""
 }
 
-func (x *SearchList) GetPublishTime() int64 {
+func (x *SearchList) GetPublishTime() string {
 	if x != nil {
 		return x.PublishTime
 	}
-	return 0
+	return ""
 }
 
 func (x *SearchList) GetFileExists() bool {
@@ -721,25 +719,11 @@ func (x *SearchList) GetAgencyTel() string {
 	return ""
 }
 
-func (x *SearchList) GetWinner() string {
-	if x != nil {
-		return x.Winner
-	}
-	return ""
-}
-
-func (x *SearchList) GetWinnerPerson() string {
-	if x != nil {
-		return x.WinnerPerson
-	}
-	return ""
-}
-
-func (x *SearchList) GetWinnerTel() string {
+func (x *SearchList) GetWinnerInfo() []*WinnerInfo {
 	if x != nil {
-		return x.WinnerTel
+		return x.WinnerInfo
 	}
-	return ""
+	return nil
 }
 
 func (x *SearchList) GetBidOpenTime() string {
@@ -784,6 +768,78 @@ func (x *SearchList) GetProjectInfo() *PInfo {
 	return nil
 }
 
+//
+type WinnerInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Winner       string `protobuf:"bytes,1,opt,name=winner,proto3" json:"winner,omitempty"`
+	WinnerTel    string `protobuf:"bytes,2,opt,name=winnerTel,proto3" json:"winnerTel,omitempty"`
+	WinnerPerson string `protobuf:"bytes,3,opt,name=winnerPerson,proto3" json:"winnerPerson,omitempty"`
+	WinnerId     string `protobuf:"bytes,4,opt,name=winnerId,proto3" json:"winnerId,omitempty"`
+}
+
+func (x *WinnerInfo) Reset() {
+	*x = WinnerInfo{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_bxcore_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *WinnerInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*WinnerInfo) ProtoMessage() {}
+
+func (x *WinnerInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_bxcore_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use WinnerInfo.ProtoReflect.Descriptor instead.
+func (*WinnerInfo) Descriptor() ([]byte, []int) {
+	return file_bxcore_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *WinnerInfo) GetWinner() string {
+	if x != nil {
+		return x.Winner
+	}
+	return ""
+}
+
+func (x *WinnerInfo) GetWinnerTel() string {
+	if x != nil {
+		return x.WinnerTel
+	}
+	return ""
+}
+
+func (x *WinnerInfo) GetWinnerPerson() string {
+	if x != nil {
+		return x.WinnerPerson
+	}
+	return ""
+}
+
+func (x *WinnerInfo) GetWinnerId() string {
+	if x != nil {
+		return x.WinnerId
+	}
+	return ""
+}
+
 //
 type PInfo struct {
 	state         protoimpl.MessageState
@@ -802,7 +858,7 @@ type PInfo struct {
 func (x *PInfo) Reset() {
 	*x = PInfo{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_bxcore_proto_msgTypes[4]
+		mi := &file_bxcore_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -815,7 +871,7 @@ func (x *PInfo) String() string {
 func (*PInfo) ProtoMessage() {}
 
 func (x *PInfo) ProtoReflect() protoreflect.Message {
-	mi := &file_bxcore_proto_msgTypes[4]
+	mi := &file_bxcore_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -828,7 +884,7 @@ func (x *PInfo) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PInfo.ProtoReflect.Descriptor instead.
 func (*PInfo) Descriptor() ([]byte, []int) {
-	return file_bxcore_proto_rawDescGZIP(), []int{4}
+	return file_bxcore_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *PInfo) GetApproveCode() string {
@@ -898,7 +954,7 @@ type SearchLimitReq struct {
 func (x *SearchLimitReq) Reset() {
 	*x = SearchLimitReq{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_bxcore_proto_msgTypes[5]
+		mi := &file_bxcore_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -911,7 +967,7 @@ func (x *SearchLimitReq) String() string {
 func (*SearchLimitReq) ProtoMessage() {}
 
 func (x *SearchLimitReq) ProtoReflect() protoreflect.Message {
-	mi := &file_bxcore_proto_msgTypes[5]
+	mi := &file_bxcore_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -924,7 +980,7 @@ func (x *SearchLimitReq) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use SearchLimitReq.ProtoReflect.Descriptor instead.
 func (*SearchLimitReq) Descriptor() ([]byte, []int) {
-	return file_bxcore_proto_rawDescGZIP(), []int{5}
+	return file_bxcore_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *SearchLimitReq) GetAppid() string {
@@ -990,7 +1046,7 @@ type SearchLimitResp struct {
 func (x *SearchLimitResp) Reset() {
 	*x = SearchLimitResp{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_bxcore_proto_msgTypes[6]
+		mi := &file_bxcore_proto_msgTypes[7]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1003,7 +1059,7 @@ func (x *SearchLimitResp) String() string {
 func (*SearchLimitResp) ProtoMessage() {}
 
 func (x *SearchLimitResp) ProtoReflect() protoreflect.Message {
-	mi := &file_bxcore_proto_msgTypes[6]
+	mi := &file_bxcore_proto_msgTypes[7]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1016,7 +1072,7 @@ func (x *SearchLimitResp) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use SearchLimitResp.ProtoReflect.Descriptor instead.
 func (*SearchLimitResp) Descriptor() ([]byte, []int) {
-	return file_bxcore_proto_rawDescGZIP(), []int{6}
+	return file_bxcore_proto_rawDescGZIP(), []int{7}
 }
 
 func (x *SearchLimitResp) GetErrCode() int64 {
@@ -1044,7 +1100,7 @@ var File_bxcore_proto protoreflect.FileDescriptor
 
 var file_bxcore_proto_rawDesc = []byte{
 	0x0a, 0x0c, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
-	0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x22, 0xa7, 0x07, 0x0a, 0x09, 0x53, 0x65, 0x61, 0x72, 0x63,
+	0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x22, 0xa5, 0x07, 0x0a, 0x09, 0x53, 0x65, 0x61, 0x72, 0x63,
 	0x68, 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, 0x16, 0x0a, 0x06, 0x75, 0x73,
 	0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72,
@@ -1095,146 +1151,151 @@ var file_bxcore_proto_rawDesc = []byte{
 	0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x1b, 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, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
-	0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x46, 0x72,
-	0x65, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x46, 0x72, 0x65, 0x65,
-	0x12, 0x2c, 0x0a, 0x11, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4b, 0x65, 0x79,
-	0x57, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x69, 0x6e, 0x74,
-	0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x30,
-	0x0a, 0x13, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4f, 0x74, 0x68, 0x65, 0x72,
-	0x57, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x69, 0x6e, 0x74,
-	0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x64, 0x73,
-	0x22, 0x68, 0x0a, 0x0a, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 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, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
-	0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xb2, 0x02, 0x0a, 0x0a, 0x53,
-	0x65, 0x61, 0x72, 0x63, 0x68, 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,
-	0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x69,
-	0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x69, 0x73,
-	0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
-	0x4b, 0x65, 0x79, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x69, 0x73, 0x74,
-	0x6f, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18,
-	0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53,
-	0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12,
-	0x1c, 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x18, 0x06, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x16, 0x0a,
-	0x06, 0x72, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72,
-	0x65, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65,
-	0x70, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x69,
-	0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x30, 0x0a,
-	0x13, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x57,
-	0x6f, 0x72, 0x64, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x69, 0x6e, 0x74, 0x65,
-	0x72, 0x63, 0x65, 0x70, 0x74, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x22,
-	0xd3, 0x07, 0x0a, 0x0a, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x0e,
-	0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12,
-	0x0a, 0x04, 0x61, 0x72, 0x65, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72,
-	0x65, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x72, 0x65, 0x61, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x72, 0x65, 0x61, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a,
-	0x62, 0x75, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0a, 0x62, 0x75, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04,
-	0x63, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79,
-	0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x75,
-	0x73, 0x74, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x75,
-	0x73, 0x74, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79,
-	0x55, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x64, 0x75, 0x73,
-	0x74, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73,
-	0x68, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x75, 0x62,
-	0x6c, 0x69, 0x73, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65,
-	0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x69,
-	0x6c, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x74,
-	0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x74, 0x79,
-	0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x55, 0x72, 0x6c,
-	0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x55,
-	0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x43, 0x6f,
-	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69,
-	0x73, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x72,
-	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b,
-	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16,
-	0x0a, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
-	0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x69, 0x64, 0x41, 0x6d, 0x6f,
-	0x75, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x69, 0x64, 0x41, 0x6d,
-	0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x79, 0x65, 0x72, 0x18, 0x13, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x75, 0x79, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75,
-	0x79, 0x65, 0x72, 0x54, 0x65, 0x6c, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75,
-	0x79, 0x65, 0x72, 0x54, 0x65, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x75, 0x79, 0x65, 0x72, 0x50,
-	0x65, 0x72, 0x73, 0x6f, 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x75, 0x79,
-	0x65, 0x72, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e,
-	0x63, 0x79, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79,
-	0x12, 0x22, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e,
-	0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x65,
-	0x72, 0x73, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x54, 0x65,
-	0x6c, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x54,
-	0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x19, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x06, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x77, 0x69,
-	0x6e, 0x6e, 0x65, 0x72, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0c, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x1c,
-	0x0a, 0x09, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x65, 0x6c, 0x18, 0x1b, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x09, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x65, 0x6c, 0x12, 0x20, 0x0a, 0x0b,
-	0x62, 0x69, 0x64, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0b, 0x62, 0x69, 0x64, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x20,
-	0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x1d, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65,
-	0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x69, 0x64, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x1e,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x69, 0x64, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65,
-	0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x74, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x73, 0x69, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x70, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f,
-	0x64, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x70, 0x69, 0x64, 0x65, 0x72,
-	0x43, 0x6f, 0x64, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49,
-	0x6e, 0x66, 0x6f, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x78, 0x63, 0x6f,
-	0x72, 0x65, 0x2e, 0x50, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
-	0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x83, 0x02, 0x0a, 0x05, 0x50, 0x49, 0x6e, 0x66, 0x6f, 0x12,
-	0x20, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x64,
-	0x65, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74,
-	0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x72, 0x6f,
-	0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x70, 0x70,
-	0x72, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
-	0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x70, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61,
-	0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x0d, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65,
-	0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x54,
-	0x69, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79,
-	0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
-	0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65,
-	0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x70,
-	0x70, 0x72, 0x6f, 0x76, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xc2, 0x01, 0x0a, 0x0e,
-	0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x12, 0x14,
-	0x0a, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61,
-	0x70, 0x70, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x75, 0x74, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x75, 0x74, 0x12, 0x14,
-	0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63,
-	0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x6c, 0x61, 0x67, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x03, 0x52, 0x04, 0x66, 0x6c, 0x61, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x63,
-	0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x70, 0x65,
-	0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72,
-	0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64,
-	0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65,
-	0x22, 0x59, 0x0a, 0x0f, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 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, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x80, 0x01, 0x0a, 0x06,
-	0x42, 0x78, 0x43, 0x6f, 0x72, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x53, 0x65, 0x61,
-	0x72, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65,
-	0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x62, 0x78, 0x63,
-	0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3e,
-	0x0a, 0x0b, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x2e,
-	0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d,
-	0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53,
-	0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0a,
-	0x5a, 0x08, 0x2e, 0x2f, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x33,
+	0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x50, 0x61,
+	0x79, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x50, 0x61, 0x79, 0x12, 0x2c,
+	0x0a, 0x11, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x57, 0x6f,
+	0x72, 0x64, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x63, 0x65, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x13,
+	0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x57, 0x6f,
+	0x72, 0x64, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x63, 0x65, 0x70, 0x74, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x22, 0x68,
+	0x0a, 0x0a, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 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, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x44, 0x61,
+	0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xb2, 0x02, 0x0a, 0x0a, 0x53, 0x65, 0x61,
+	0x72, 0x63, 0x68, 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, 0x1a, 0x0a,
+	0x08, 0x6b, 0x65, 0x79, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x6b, 0x65, 0x79, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x73, 0x4c,
+	0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x69, 0x73, 0x4c, 0x69,
+	0x6d, 0x69, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4b, 0x65,
+	0x79, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72,
+	0x79, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20,
+	0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61,
+	0x72, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x1c, 0x0a,
+	0x09, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x09, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x72,
+	0x65, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x6d,
+	0x61, 0x72, 0x6b, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74,
+	0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x69, 0x6e, 0x74,
+	0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x69,
+	0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x57, 0x6f, 0x72,
+	0x64, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63,
+	0x65, 0x70, 0x74, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x22, 0xad, 0x07,
+	0x0a, 0x0a, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04,
+	0x61, 0x72, 0x65, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x65, 0x61,
+	0x12, 0x18, 0x0a, 0x07, 0x61, 0x72, 0x65, 0x61, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x07, 0x61, 0x72, 0x65, 0x61, 0x55, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x75,
+	0x79, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
+	0x62, 0x75, 0x79, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x69,
+	0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79, 0x12, 0x16,
+	0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+	0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74,
+	0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74,
+	0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x79, 0x55, 0x72,
+	0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72,
+	0x79, 0x55, 0x72, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x54,
+	0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69,
+	0x73, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x78,
+	0x69, 0x73, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65,
+	0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70,
+	0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65,
+	0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x0c,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x55, 0x72, 0x6c,
+	0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x43, 0x6f, 0x6c, 0x6c,
+	0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x43,
+	0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a,
+	0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70,
+	0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x72,
+	0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06,
+	0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x62, 0x75,
+	0x64, 0x67, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x62, 0x69, 0x64, 0x41, 0x6d, 0x6f, 0x75, 0x6e,
+	0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x69, 0x64, 0x41, 0x6d, 0x6f, 0x75,
+	0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x79, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x62, 0x75, 0x79, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x79, 0x65,
+	0x72, 0x54, 0x65, 0x6c, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x79, 0x65,
+	0x72, 0x54, 0x65, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x75, 0x79, 0x65, 0x72, 0x50, 0x65, 0x72,
+	0x73, 0x6f, 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x75, 0x79, 0x65, 0x72,
+	0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79,
+	0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x22,
+	0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x18, 0x17,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x65, 0x72, 0x73,
+	0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x54, 0x65, 0x6c, 0x18,
+	0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x54, 0x65, 0x6c,
+	0x12, 0x32, 0x0a, 0x0a, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x19,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x57, 0x69,
+	0x6e, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72,
+	0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x69, 0x64, 0x4f, 0x70, 0x65, 0x6e, 0x54,
+	0x69, 0x6d, 0x65, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x69, 0x64, 0x4f, 0x70,
+	0x65, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x45, 0x6e,
+	0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x69, 0x67,
+	0x6e, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x69, 0x64, 0x45,
+	0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x69,
+	0x64, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x74, 0x65,
+	0x18, 0x1d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a,
+	0x73, 0x70, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0a, 0x73, 0x70, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2f, 0x0a, 0x0b,
+	0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x1f, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x49, 0x6e, 0x66, 0x6f,
+	0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x82, 0x01,
+	0x0a, 0x0a, 0x57, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06,
+	0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x77, 0x69,
+	0x6e, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x65,
+	0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x54,
+	0x65, 0x6c, 0x12, 0x22, 0x0a, 0x0c, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x50, 0x65, 0x72, 0x73,
+	0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72,
+	0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72,
+	0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x69, 0x6e, 0x6e, 0x65, 0x72,
+	0x49, 0x64, 0x22, 0x83, 0x02, 0x0a, 0x05, 0x50, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b,
+	0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x26,
+	0x0a, 0x0e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x43,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76,
+	0x65, 0x44, 0x65, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x70, 0x70,
+	0x72, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x70, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x70, 0x70, 0x72,
+	0x6f, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0d, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20,
+	0x0a, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65,
+	0x12, 0x20, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79,
+	0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x4e, 0x75, 0x6d,
+	0x62, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x70, 0x70, 0x72, 0x6f,
+	0x76, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xc2, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x61,
+	0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x61,
+	0x70, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x69,
+	0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63,
+	0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e,
+	0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x6c, 0x61, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x04, 0x66, 0x6c, 0x61, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74,
+	0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x63, 0x65,
+	0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a,
+	0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x22, 0x59, 0x0a,
+	0x0f, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 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, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0x80, 0x01, 0x0a, 0x06, 0x42, 0x78, 0x43,
+	0x6f, 0x72, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
+	0x4c, 0x69, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65,
+	0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65,
+	0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3e, 0x0a, 0x0b, 0x53,
+	0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x2e, 0x62, 0x78, 0x63,
+	0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52,
+	0x65, 0x71, 0x1a, 0x17, 0x2e, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, 0x61, 0x72,
+	0x63, 0x68, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x42, 0x0a, 0x5a, 0x08, 0x2e,
+	0x2f, 0x62, 0x78, 0x63, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -1249,29 +1310,31 @@ func file_bxcore_proto_rawDescGZIP() []byte {
 	return file_bxcore_proto_rawDescData
 }
 
-var file_bxcore_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_bxcore_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
 var file_bxcore_proto_goTypes = []interface{}{
 	(*SearchReq)(nil),       // 0: bxcore.SearchReq
 	(*SearchResp)(nil),      // 1: bxcore.SearchResp
 	(*SearchData)(nil),      // 2: bxcore.SearchData
 	(*SearchList)(nil),      // 3: bxcore.SearchList
-	(*PInfo)(nil),           // 4: bxcore.PInfo
-	(*SearchLimitReq)(nil),  // 5: bxcore.SearchLimitReq
-	(*SearchLimitResp)(nil), // 6: bxcore.SearchLimitResp
+	(*WinnerInfo)(nil),      // 4: bxcore.WinnerInfo
+	(*PInfo)(nil),           // 5: bxcore.PInfo
+	(*SearchLimitReq)(nil),  // 6: bxcore.SearchLimitReq
+	(*SearchLimitResp)(nil), // 7: bxcore.SearchLimitResp
 }
 var file_bxcore_proto_depIdxs = []int32{
 	2, // 0: bxcore.SearchResp.data:type_name -> bxcore.SearchData
 	3, // 1: bxcore.SearchData.list:type_name -> bxcore.SearchList
-	4, // 2: bxcore.SearchList.projectInfo:type_name -> bxcore.PInfo
-	0, // 3: bxcore.BxCore.GetSearchList:input_type -> bxcore.SearchReq
-	5, // 4: bxcore.BxCore.SearchLimit:input_type -> bxcore.SearchLimitReq
-	1, // 5: bxcore.BxCore.GetSearchList:output_type -> bxcore.SearchResp
-	6, // 6: bxcore.BxCore.SearchLimit:output_type -> bxcore.SearchLimitResp
-	5, // [5:7] is the sub-list for method output_type
-	3, // [3:5] is the sub-list for method input_type
-	3, // [3:3] is the sub-list for extension type_name
-	3, // [3:3] is the sub-list for extension extendee
-	0, // [0:3] is the sub-list for field type_name
+	4, // 2: bxcore.SearchList.winnerInfo:type_name -> bxcore.WinnerInfo
+	5, // 3: bxcore.SearchList.projectInfo:type_name -> bxcore.PInfo
+	0, // 4: bxcore.BxCore.GetSearchList:input_type -> bxcore.SearchReq
+	6, // 5: bxcore.BxCore.SearchLimit:input_type -> bxcore.SearchLimitReq
+	1, // 6: bxcore.BxCore.GetSearchList:output_type -> bxcore.SearchResp
+	7, // 7: bxcore.BxCore.SearchLimit:output_type -> bxcore.SearchLimitResp
+	6, // [6:8] is the sub-list for method output_type
+	4, // [4:6] is the sub-list for method input_type
+	4, // [4:4] is the sub-list for extension type_name
+	4, // [4:4] is the sub-list for extension extendee
+	0, // [0:4] is the sub-list for field type_name
 }
 
 func init() { file_bxcore_proto_init() }
@@ -1329,7 +1392,7 @@ func file_bxcore_proto_init() {
 			}
 		}
 		file_bxcore_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PInfo); i {
+			switch v := v.(*WinnerInfo); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1341,7 +1404,7 @@ func file_bxcore_proto_init() {
 			}
 		}
 		file_bxcore_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*SearchLimitReq); i {
+			switch v := v.(*PInfo); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1353,6 +1416,18 @@ func file_bxcore_proto_init() {
 			}
 		}
 		file_bxcore_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SearchLimitReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_bxcore_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*SearchLimitResp); i {
 			case 0:
 				return &v.state
@@ -1371,7 +1446,7 @@ func file_bxcore_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_bxcore_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   7,
+			NumMessages:   8,
 			NumExtensions: 0,
 			NumServices:   1,
 		},

+ 106 - 468
jyBXCore/rpc/util/search.go

@@ -3,7 +3,6 @@ package util
 import (
 	MC "app.yhyue.com/moapp/jybase/common"
 	ME "app.yhyue.com/moapp/jybase/encrypt"
-	elastic "app.yhyue.com/moapp/jybase/esv1"
 	"crypto/rand"
 	"encoding/json"
 	"fmt"
@@ -11,7 +10,6 @@ import (
 	"io/ioutil"
 	IC "jyBXCore/rpc/init"
 	"jyBXCore/rpc/internal/config"
-	"jyBXCore/rpc/model/es"
 	"jyBXCore/rpc/type/bxcore"
 	"math/big"
 	"net/http"
@@ -62,7 +60,7 @@ func SearchHistory(history, searchValue, additionalWords string) (arrs []string)
 	return arrs
 }
 
-func FilteKey(k string) string {
+func FilterKey(k string) string {
 	k = strings.TrimSpace(k)
 	k = filterReg_3.ReplaceAllString(k, "")
 	k = filterReg_2.ReplaceAllString(k, "")
@@ -76,7 +74,7 @@ func FilteKey(k string) string {
 // b_word:截取后的关键词;a_word:截取后 后面三个字;s_word:已截取 处理过的关键词
 func InterceptSearchKW(word string, keywordsLimit int, isFilter bool) (b_word, a_word, s_word string) {
 	if isFilter {
-		word = FilteKey(word)
+		word = FilterKey(word)
 	}
 	word = MatchSpace.ReplaceAllString(strings.TrimSpace(word), " ")
 	words := []rune(word)
@@ -112,7 +110,7 @@ func HttpEs(ques, analyzer, esAddress string) (res string) {
 	resp, err := http.Get(URL.String())
 	if err != nil {
 		logx.Info("es连接失败 err1:", err)
-		resp, err = getesResp(ques, analyzer, addrs)
+		resp, err = getESResp(ques, analyzer, addrs)
 		if err != nil {
 			return
 		}
@@ -140,7 +138,7 @@ func HttpEs(ques, analyzer, esAddress string) (res string) {
 }
 
 //
-func getesResp(ques, analyzer string, addrs []string) (resp *http.Response, err error) {
+func getESResp(ques, analyzer string, addrs []string) (resp *http.Response, err error) {
 	for _, v := range addrs {
 		surl := v + "/bidding/_analyze"
 		URL, _ := url.Parse(surl)
@@ -156,410 +154,18 @@ func getesResp(ques, analyzer string, addrs []string) (resp *http.Response, err
 	return resp, err
 }
 
-//pc、微信、app 招标信息搜索
-
 const (
-	INDEX          = "bidding"
-	TYPE           = "bidding"
-	bidSearch_sort = `{"dataweight":-1,"publishtime":-1}`
-	RedisName      = "other"
+	RedisName    = "other"
+	RedisNameNew = "newother"
 	//招标搜索分页--每页显示数量
 	SearchPageSize = 50
 	//招标搜索分页--最大页数
 	SearchMaxPageNum       = 10  //免费用户500条记录
 	SearchMaxPageNum_PAYED = 100 //付费用户5000条记录
 
-	bidSearch_field_1    = `"_id","title","publishtime","dataweight","toptype","subtype","type","area","city","s_subscopeclass","bidamount","budget","buyerclass","spidercode","site"` //,"filetext"
-	bidSearch_field      = bidSearch_field_1 + `,"bidopentime","winner","buyer","projectname","projectcode","projectinfo"`
-	bidSearch_field_file = `,"filetext","isValidFile"`
-	query_bool_should    = `{"bool":{"should":[%s],"minimum_should_match": 1}}`
 )
 
-//GetBidSearchData 标信息搜索
-func GetBidSearchData(in *bxcore.SearchReq) (count int64, list []*bxcore.SearchList) {
-	t := time.Now()
-	var hightlightContent bool = false //是否高亮正文
-	var selectTypeArr = strings.Split(in.SelectType, ",")
-	for _, v := range selectTypeArr {
-		if v == "detail" {
-			hightlightContent = true
-			break
-		}
-	}
-	qstr := GetSearchQuery(in, GetBidSearchQuery(in))
-	var start = int((in.PageNum - 1) * in.PageSize)
-	if start >= 0 {
-		field := bidSearch_field_1
-		if start == 0 {
-			field = bidSearch_field
-		}
-		if IC.C.FileSignBool {
-			field = field + bidSearch_field_file
-		}
-		biddingSearch := es.EsSearch{
-			Index:      INDEX,
-			Itype:      TYPE,
-			Query:      qstr,
-			FindFields: "detail",
-			Order:      bidSearch_sort,
-			Fields:     field,
-			Start:      start,
-			Limit:      int(in.PageSize),
-			Count:      0,
-			HighLight:  false,
-		}
-		var repl *[]map[string]interface{}
-		if hightlightContent {
-			biddingSearch.Count = 115
-			biddingSearch.HighLight = hightlightContent
-		}
-		//repl = elastic.GetAllByNgram(INDEX, TYPE, qstr, ``, bidSearch_sort, field, start, int(in.PageSize), 0, false)
-		count, repl = biddingSearch.GetAllByNgramWithCount()
-		if repl != nil && *repl != nil && len(*repl) > 0 {
-			BidListConvert(in.Industry, repl)
-			list = SearchListFormart(repl, true)
-		}
-		logx.Info("关键词 -1- 查询耗时:", time.Since(t).Seconds())
-		MakeCollection(in.UserId, list)
-	}
-	logx.Info("关键词 查询耗时:", time.Since(t).Seconds())
-	return
-}
-
-//
-var topTypeMap = map[string]string{
-	"招标预告":   "预告",
-	"招标公告":   "招标",
-	"招标结果":   "结果",
-	"招标信用信息": "其它",
-	"拟建项目":   "拟建",
-	"采购意向":   "采购意向",
-}
-
-//
-func GetBidSearchQuery(in *bxcore.SearchReq) string {
-	query := ``
-	//省份
-	area := in.Province
-	if area != "" {
-		query += `{"terms":{"area":[`
-		for k, v := range strings.Split(area, ",") {
-			if k > 0 {
-				query += `,`
-			}
-			query += `"` + v + `"`
-		}
-		query += `]}}`
-	}
-	//
-	city := in.City
-	if city != "" {
-		if len(query) > 0 {
-			query += ","
-		}
-		query += `{"terms":{"city":[`
-		for k, v := range strings.Split(city, ",") {
-			if k > 0 {
-				query += `,`
-			}
-			query += `"` + v + `"`
-		}
-		query += `]}}`
-	}
-	if query != "" {
-		query = fmt.Sprintf(query_bool_should, query)
-	}
-	//发布时间
-	publishtime := in.PublishTime
-	if publishtime != "" && len(strings.Split(publishtime, "-")) > 1 {
-		if len(query) > 0 {
-			query += ","
-		}
-		starttime := strings.Split(publishtime, "-")[0]
-		endtime := strings.Split(publishtime, "-")[1]
-		query += `{"range":{"publishtime":{`
-		if starttime != "" {
-			query += `"gte":` + starttime
-		}
-		if starttime != "" && endtime != "" {
-			query += `,`
-		}
-		if endtime != "" {
-			query += `"lt":` + endtime
-		}
-		query += `}}}`
-	}
-	//信息类型-二级
-	subtype := in.Subtype
-	toptype := MC.If(in.TopType != "", strings.Split(in.TopType, ","), []string{}).([]string)
-	alltype := ``
-	//二级分类
-	if subtype != "" {
-		var typeInt = 0
-		alltype += `{"terms":{"subtype":[`
-		for k, v := range strings.Split(subtype, ",") {
-			if ttype := MC.If(topTypeMap[v] != "" && in.TopType == "", topTypeMap[v], "").(string); ttype != "" {
-				toptype = append(toptype, ttype)
-				typeInt += 1
-				continue
-			}
-			if k > typeInt {
-				alltype += `,`
-			}
-			alltype += `"` + v + `"`
-		}
-		alltype += `]}}`
-	}
-	//信息类型  一级分类
-	logx.Info("toptype:", toptype)
-	if len(toptype) > 0 {
-		if alltype != "" {
-			alltype += ","
-		}
-		alltype += `{"terms":{"toptype":[`
-		for k, v := range toptype {
-			if k > 0 {
-				alltype += `,`
-			}
-			alltype += `"` + v + `"`
-		}
-		alltype += `]}}`
-	}
-
-	if alltype != "" {
-		if query != "" {
-			query += ","
-		}
-		query += fmt.Sprintf(query_bool_should, alltype)
-	}
-	//采购单位类型
-	buyerclass := in.BuyerClass
-	if buyerclass != "" {
-		if len(query) > 0 {
-			query += ","
-		}
-		query += `{"terms":{"buyerclass":[`
-		for k, v := range strings.Split(buyerclass, ",") {
-			if k > 0 {
-				query += `,`
-			}
-			query += `"` + v + `"`
-		}
-		query += `]}}`
-	}
-	return query
-}
-
-//包含正文或 附件 不包含标题
-func DetailFileORTitle(findfields string) bool {
-	return (strings.Contains(findfields, `"detail"`) || strings.Contains(findfields, `"filetext"`)) && !strings.Contains(findfields, `"title"`)
-}
-func GetSearchQuery(in *bxcore.SearchReq, mustquery string) (qstr string) {
-	multi_match := `{"multi_match": {"query": "%s","type": "phrase", "fields": [%s]}}`
-	query := `{"query":{"bool":{"must":[%s],"must_not":[%s]}}}`
-	//query := `{"query": {"function_score": {"query": {"bool": {"must": [%s],"must_not": [%s]}},"field_value_factor": {"field": "dataweight","modifier": "ln1p","missing": 0}}}}`
-
-	query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
-	query_bools_must := `{"bool":{"must":[{"range":{"bidamount":{%s}}}]}},{"bool":{"must":[{"range":{"budget":{%s}}}],"must_not":[{"range":{"bidamount":{"gte":-1}}}]}}`
-	query_bool_must := `{"bool":{"must":[{"terms":{"s_subscopeclass":[%s]}}]}}`
-	query_bool_must_term := `{"bool": {"must": [{ "term": {"isValidFile": %d }}]}}`
-	query_missing := `{"constant_score":{"filter":{"missing":{"field":"%s"}}}}`
-	gte := `"gte": %s`
-	lte := `"lte": %s`
-	musts, must_not := []string{}, []string{}
-	if mustquery != "" {
-		musts = append(musts, mustquery)
-	}
-	//搜索范围是否只有附件
-	//搜索范围只选择附件,是否有附件条件无效;
-	var isFileSearch bool = in.SelectType == "filetext"
-	selectTypeArr := strings.Split(in.SelectType, ",")
-	var findfields string
-	if selectTypeArr == nil || len(selectTypeArr) == 0 {
-		findfields = `"title"`
-	} else {
-		findfields = fmt.Sprintf(`"%s"`, strings.Join(selectTypeArr, "\",\""))
-	}
-	//此时关键词中间有+进行隔离
-	if in.KeyWords != "" {
-		shoulds := []string{}
-		var switchBool = strings.Contains(findfields, "detail") && strings.Contains(findfields, "title") && IC.C.SearchTypeSwitch
-		keyword_multi_match := fmt.Sprintf(multi_match, "%s", findfields)
-		for _, v := range strings.Split(in.KeyWords, "+") {
-			if elastic.ReplaceYH(v) == "" {
-				continue
-			}
-			if len([]rune(elastic.ReplaceYH(v))) == 1 {
-				//单个字  搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
-				if DetailFileORTitle(findfields) {
-					keyword_multi_match = fmt.Sprintf(multi_match, "%s", findfields+`,"title"`)
-				}
-			} else {
-				//标题 全文搜索 搜索类型开关打开 默认搜索全文;(全文包含标题)(单字排除)
-				if switchBool && len([]rune(elastic.ReplaceYH(v))) > 1 {
-					if strings.Contains(findfields, `"title",`) {
-						findfields = strings.Replace(findfields, `"title",`, ``, -1)
-					} else if strings.Contains(findfields, `,"title"`) {
-						findfields = strings.Replace(findfields, `,"title"`, ``, -1)
-					}
-					keyword_multi_match = fmt.Sprintf(multi_match, "%s", findfields)
-				}
-			}
-			shoulds = append(shoulds, fmt.Sprintf(keyword_multi_match, elastic.ReplaceYH(v)))
-		}
-		musts = append(musts, fmt.Sprintf(elastic.NgramMust, strings.Join(shoulds, ",")))
-	}
-	if in.Industry != "" {
-		industrys := strings.Split(in.Industry, ",")
-		musts = append(musts, fmt.Sprintf(query_bool_must, `"`+strings.Join(industrys, `","`)+`"`))
-	}
-	//价格
-	if in.Price != "" && len(strings.Split(in.Price, "-")) > 1 {
-		minprice, maxprice := strings.Split(in.Price, "-")[0], strings.Split(in.Price, "-")[1]
-		if minprice != "" || maxprice != "" {
-			sq := ``
-			if minprice != "" {
-				min, _ := strconv.ParseFloat(minprice, 64)
-				minprice = fmt.Sprintf("%.0f", min*10000)
-				if minprice == "0" {
-					minprice = ""
-				}
-			}
-			if maxprice != "" {
-				max, _ := strconv.ParseFloat(maxprice, 64)
-				maxprice = fmt.Sprintf("%.0f", max*10000)
-				if maxprice == "0" {
-					maxprice = ""
-				}
-			}
-			if minprice != "" {
-				sq += fmt.Sprintf(gte, minprice)
-			}
-			if minprice != "" && maxprice != "" {
-				sq += `,`
-			}
-			if maxprice != "" {
-				sq += fmt.Sprintf(lte, maxprice)
-			}
-			if minprice != "" || maxprice != "" {
-				query_price := fmt.Sprintf(query_bool_should, fmt.Sprintf(query_bools_must, sq, sq))
-				musts = append(musts, query_price)
-			}
-		}
-	}
-	hasBuyerTel := in.BuyerTel
-	if hasBuyerTel != "" {
-		if hasBuyerTel == "y" {
-			must_not = append(must_not, fmt.Sprintf(query_missing, "buyertel"))
-		} else {
-			musts = append(musts, fmt.Sprintf(query_missing, "buyertel"))
-		}
-	}
-	hasWinnerTel := in.WinnerTel
-	if hasWinnerTel != "" {
-		if hasWinnerTel == "y" {
-			must_not = append(must_not, fmt.Sprintf(query_missing, "winnertel"))
-		} else {
-			musts = append(musts, fmt.Sprintf(query_missing, "winnertel"))
-		}
-	}
-	//排除词
-	notkey := in.ExclusionWords
-	if notkey = strings.TrimSpace(notkey); notkey != "" {
-		notkey_multi_match := fmt.Sprintf(multi_match, "%s", findfields)
-		notkey_must_not := []string{}
-		for _, v := range strings.Split(notkey, " ") {
-			v = strings.TrimSpace(v)
-			if v == "" {
-				continue
-			}
-			if len([]rune(elastic.ReplaceYH(v))) == 1 {
-				//单个字 搜索范围 有全文或者附件 无标题 例如:学 虚拟机 detail  搜索的时候加上标题
-				if DetailFileORTitle(findfields) {
-					notkey_multi_match = fmt.Sprintf(multi_match, "%s", findfields+`,"title"`)
-				}
-			}
-			notkey_must_not = append(notkey_must_not, fmt.Sprintf(notkey_multi_match, elastic.ReplaceYH(v)))
-		}
-		must_not = append(must_not, fmt.Sprintf(query_bool_should, strings.Join(notkey_must_not, ",")))
-	}
-	//
-	fileExists := in.FileExists
-	if !isFileSearch && fileExists != "" {
-		if fileExists == "1" { //有附件
-			must_not = append(must_not, fmt.Sprintf(query_missing, "isValidFile"))
-			musts = append(musts, fmt.Sprintf(query_bool_must_term, 1))
-		} else if fileExists == "-1" { //无附件
-			musts = append(musts, fmt.Sprintf(query_missing, "isValidFile"))
-		}
-	}
-	qstr = fmt.Sprintf(query, strings.Join(musts, ","), strings.Join(must_not, ","))
-	logx.Info(qstr)
-	return
-}
-
-/*
- * 结果列表转换,目前只换行行业字段
- * 所有的招标搜索都要调用此方法,列表中有展示行业的也可以用
- * industry 搜索条件中的行业,默认为空
- */
-func BidListConvert(industry string, res *[]map[string]interface{}) {
-	if res == nil {
-		return
-	}
-	commonSubstring := func(v string) (value string) {
-		bcs := strings.Split(v, "_")
-		if len(bcs) == 1 {
-			value = bcs[0]
-		} else if len(bcs) == 2 {
-			value = bcs[0]
-			if strings.TrimSpace(value) == "" {
-				value = bcs[0]
-			}
-		}
-		return
-	}
-	for _, v := range *res {
-		v["id"] = v["_id"]
-		delete(v, "_id")
-		budget, _ := v["budget"].(float64)
-		bidamount, _ := v["bidamount"].(float64)
-		if budget == 0 || strings.TrimSpace(fmt.Sprint(v["budget"])) == "" {
-			delete(v, "budget")
-		}
-		if bidamount == 0 || strings.TrimSpace(fmt.Sprint(v["bidamount"])) == "" {
-			delete(v, "bidamount")
-		}
-		value := ""
-		subscopeclass, _ := v["s_subscopeclass"].(string)
-		subscopeclass = strings.Trim(subscopeclass, ",")
-		bct := strings.Split(subscopeclass, ",")
-		if bct == nil || len(bct) == 0 {
-			continue
-		}
-		//搜索条件中没有行业的话,取查询结果中第一个行业
-		if industry == "" {
-			value = commonSubstring(bct[0])
-		} else { //搜索条件中有行业的话,取行业中和搜索条件相对应的第一个
-			industrys := strings.Split(industry, ",")
-		L:
-			for _, bc := range bct {
-				for _, is := range industrys {
-					if bc == is {
-						value = commonSubstring(bc)
-						break L
-					}
-				}
-			}
-		}
-		if strings.TrimSpace(value) == "" {
-			continue
-		}
-		v["industry"] = value
-	}
-}
-
-//是否收藏
+// MakeCollection 是否收藏
 func MakeCollection(userId string, list []*bxcore.SearchList) {
 	if list == nil || len(list) == 0 {
 		return
@@ -589,29 +195,47 @@ func MakeCollection(userId string, list []*bxcore.SearchList) {
 	}
 }
 
-//默认查询缓存数据
-func SearchCahcheData(in *bxcore.SearchReq) (count int64, list []*bxcore.SearchList) {
-	//最新招标信息
-	findfields := `"title"`
-	qstr := GetSearchQuery(in, GetBidSearchQuery(in))
-	//首页
-	if in.PageNum == 1 {
-		count = elastic.Count(INDEX, TYPE, qstr)
+// IndustryFormat 行业处理
+func IndustryFormat(industry, subScopeClass string) (newIndustry string) {
+	commonSubstring := func(v string) (value string) {
+		bcs := strings.Split(v, "_")
+		if len(bcs) == 1 {
+			value = bcs[0]
+		} else if len(bcs) == 2 {
+			value = bcs[0]
+			if strings.TrimSpace(value) == "" {
+				value = bcs[0]
+			}
+		}
+		return
 	}
-	if count > 0 || in.PageNum > 1 {
-		repl := elastic.GetAllByNgram(INDEX, TYPE, qstr, findfields, bidSearch_sort, bidSearch_field, int(in.PageNum), int(in.PageSize), 0, false)
-		if repl != nil && *repl != nil && len(*repl) > 0 {
-			BidListConvert(in.Industry, repl)
-			list = SearchListFormart(repl, false)
+	bct := strings.Split(subScopeClass, ",")
+	if bct == nil || len(bct) == 0 {
+		return
+	}
+	//搜索条件中没有行业的话,取查询结果中第一个行业
+	if industry == "" {
+		newIndustry = commonSubstring(bct[0])
+	} else { //搜索条件中有行业的话,取行业中和搜索条件相对应的第一个
+		industryArr := strings.Split(industry, ",")
+	L:
+		for _, bc := range bct {
+			for _, is := range industryArr {
+				if bc == is {
+					newIndustry = strings.TrimSpace(commonSubstring(bc))
+					break L
+				}
+			}
 		}
 	}
 	return
 }
 
-//格式化数据
-func SearchListFormart(repl *[]map[string]interface{}, b bool) (list []*bxcore.SearchList) {
+// SearchListFormat  格式化数据
+func SearchListFormat(industry string, repl *[]map[string]interface{}, b bool) (list []*bxcore.SearchList) {
 	for _, v := range *repl {
 		var searchList = &bxcore.SearchList{}
+		//正文
 		if b {
 			//正文匹配检索关键词
 			highlight, _ := v["highlight"].(map[string][]string)
@@ -621,65 +245,75 @@ func SearchListFormart(repl *[]map[string]interface{}, b bool) (list []*bxcore.S
 			}
 			searchList.Detail = detail
 		}
-		searchList.Area = MC.ObjToString(v["area"])
-		searchList.AreaUrl = IC.LabelMap[searchList.Area].Url
-		searchList.BuyerClass = MC.ObjToString(v["buyerclass"])
-		searchList.City = MC.ObjToString(v["city"])
-		searchList.FileExists, _ = v["isValidFile"].(bool) //附件
-		searchList.Id = ME.EncodeArticleId2ByCheck(MC.ObjToString(v["id"]))
-		searchList.Industry = MC.ObjToString(v["industry"])
-		searchList.IndustryUrl = IC.LabelMap[searchList.Industry].Url
-		searchList.PublishTime = MC.Int64All(v["publishtime"])
-		searchList.Subtype = MC.ObjToString(v["subtype"])
-		searchList.SubtypeUrl = IC.LabelMap[searchList.Subtype].Url
-		searchList.Title = MC.ObjToString(v["title"])
-		searchList.Budget = MC.Int64All(v["budget"])
-		searchList.BidAmount = MC.Int64All(v["bidamount"])
-		searchList.ProjectName = MC.ObjToString(v["projectname"])
-		searchList.ProjectCode = MC.ObjToString(v["projectcode"])
-		searchList.ProjectInfo = &bxcore.PInfo{}
+		searchList.Id = MC.ObjToString(v["_id"])                                                                    //ME.EncodeArticleId2ByCheck(MC.ObjToString(v["id"]))                                         //加密信息id
+		searchList.Area = MC.ObjToString(v["area"])                                                                 //地区
+		searchList.AreaUrl = IC.LabelMap[searchList.Area].Url                                                       //地区分类链接
+		searchList.BuyerClass = MC.ObjToString(v["buyerclass"])                                                     //采购单位类型
+		searchList.City = MC.ObjToString(v["city"])                                                                 //城市
+		searchList.Industry = IndustryFormat(industry, strings.Trim(MC.ObjToString(v["s_subscopeclass"]), ","))     //行业
+		searchList.IndustryUrl = IC.LabelMap[searchList.Industry].Url                                               //行业分类地址
+		searchList.PublishTime = MC.If(v["publishtime"] != nil, MC.LongToDate(v["publishtime"], true), "").(string) //发布时间
+		searchList.FileExists, _ = v["isValidFile"].(bool)                                                          //是否有附件
+		searchList.Subtype = MC.ObjToString(v["subtype"])                                                           //信息类型
+		searchList.SubtypeUrl = IC.LabelMap[searchList.Subtype].Url                                                 //信息类型分类链接
+		searchList.Title = MC.ObjToString(v["title"])                                                               //标题
+		searchList.ProjectName = MC.ObjToString(v["projectname"])                                                   //项目名称
+		searchList.ProjectCode = MC.ObjToString(v["projectcode"])                                                   //项目代码
+		if budget, ok := v["budget"].(float64); ok && budget > 0 {                                                  //预算
+			searchList.Budget = int64(budget)
+		}
+		if bidamount, ok := v["bidamount"].(float64); ok && bidamount > 0 { //中标金额
+			searchList.BidAmount = int64(bidamount)
+		}
+		searchList.Buyer = MC.ObjToString(v["buyer"])                                                               //采购单位
+		searchList.BuyerTel = MC.ObjToString(v["buyertel"])                                                         //采购单位联系方式
+		searchList.BuyerPerson = MC.ObjToString(v["buyerperson"])                                                   //采购单位联系人
+		searchList.Agency = MC.ObjToString(v["agency"])                                                             //代理机构
+		searchList.AgencyTel = MC.ObjToString(v["agencytel"])                                                       //代理机构联系电话
+		searchList.AgencyPerson = MC.ObjToString(v["agencyperson"])                                                 //代理机构联系人
+		searchList.BidOpenTime = MC.If(v["bidopentime"] != nil, MC.LongToDate(v["bidopentime"], true), "").(string) //开标时间
+		searchList.BidEndTime = MC.If(v["bidendtime"] != nil, MC.LongToDate(v["bidendtime"], true), "").(string)    //发布时间
+		searchList.SignEndTime = MC.If(v["signendtime"] != nil, MC.LongToDate(v["signendtime"], true), "").(string) //投标截止日期
+		searchList.Site = MC.ObjToString(v["site"])                                                                 //网站来源名称
+		searchList.SpiderCode = MC.ObjToString(v["spidercode"])                                                     //网站来源代码
+		winnerList := MC.ObjToString(v["s_winner"])                                                                 //中标企业名称集合
+		if winnerList != "" && len(strings.Split(winnerList, ",")) > 0 {
+			for wk, wv := range strings.Split(winnerList, ",") {
+				var (
+					winnerId = ""
+				)
+				if v["entidlist"] != nil {
+					if entIdList := MC.ObjArrToStringArr(v["entidlist"].([]interface{})); len(entIdList) > wk { //中标企业id集合
+						winnerId = entIdList[wk]
+					}
+				}
+				searchList.WinnerInfo = append(searchList.WinnerInfo, &bxcore.WinnerInfo{
+					Winner:       wv,                                                                       //中标企业 需要单独处理
+					WinnerTel:    MC.ObjToString(v["winnertel"]),                                           //中标企业联系电话
+					WinnerPerson: MC.ObjToString(v["winnerperson"]),                                        //中标企业联系人
+					WinnerId:     MC.If(winnerId != "", ME.EncodeArticleId2ByCheck(winnerId), "").(string), //中标企业加密id
+				})
+			}
+		}
+		searchList.ProjectInfo = &bxcore.PInfo{} //拟建项目信息
 		if v["projectinfo"] != nil {
-			pinfo := MC.ObjToMap(v["projectinfo"])
-			searchList.ProjectInfo.ApproveCode = MC.ObjToString((*pinfo)["approvecode"])
-			searchList.ProjectInfo.ApproveContent = MC.ObjToString((*pinfo)["approvecontent"])
-			searchList.ProjectInfo.ApproveDept = MC.ObjToString((*pinfo)["approvedept"])
-			searchList.ProjectInfo.ApproveStatus = MC.ObjToString((*pinfo)["approvestatus"])
-			searchList.ProjectInfo.ProjectType = MC.ObjToString((*pinfo)["projecttype"])
-			searchList.ProjectInfo.ApproveNumber = MC.ObjToString((*pinfo)["approvenumber"])
-			searchList.ProjectInfo.ApproveTime = MC.ObjToString((*pinfo)["approvetime"])
+			pInfo := MC.ObjToMap(v["projectinfo"])
+			searchList.ProjectInfo.ApproveCode = MC.ObjToString((*pInfo)["approvecode"])
+			searchList.ProjectInfo.ApproveContent = MC.ObjToString((*pInfo)["approvecontent"])
+			searchList.ProjectInfo.ApproveDept = MC.ObjToString((*pInfo)["approvedept"])
+			searchList.ProjectInfo.ApproveStatus = MC.ObjToString((*pInfo)["approvestatus"])
+			searchList.ProjectInfo.ProjectType = MC.ObjToString((*pInfo)["projecttype"])
+			searchList.ProjectInfo.ApproveNumber = MC.ObjToString((*pInfo)["approvenumber"])
+			searchList.ProjectInfo.ApproveTime = MC.ObjToString((*pInfo)["approvetime"])
 		}
-		searchList.Winner = MC.ObjToString(v["winner"])
-		searchList.Buyer = MC.ObjToString(v["buyer"])
-		searchList.BidOpenTime = MC.ObjToString(v["bidopentime"])
-		searchList.Site = MC.ObjToString(v["site"])
-		searchList.SpiderCode = MC.ObjToString(v["spidercode"])
 		list = append(list, searchList)
 	}
 	return
 }
 
-//合并map数据,去重,排序
-func DelRepeatSearchData(resOne, resTwo []*bxcore.SearchList) []*bxcore.SearchList {
-	if len(resOne) > 0 && len(resTwo) > 0 {
-		for _, v := range resOne {
-			for n, m := range resTwo {
-				if v.Id == m.Id {
-					resTwo = append(resTwo[0:n], resTwo[n+1:]...)
-					break
-				}
-			}
-		}
-		resOne = append(resOne, resTwo...)
-	} else {
-		resOne = append(resOne, resTwo...)
-	}
-	//sort.Slice(resOne, func(i, j int) bool {
-	//	return resOne[i].PublishTime > resOne[j].PublishTime
-	//})
-	return resOne
-}
-
-//付费用户搜索优化
+// IsOptimize 付费用户搜索优化
+// 需求来源:付费用户 默认查询 五年内数据,数据查询耗时,
+// 付费用户 且开关打开,针对前两页数据,满足关键词(< 7个字),查询时间范围一年以上,缩短查询时间
 func IsOptimize(cc config.Config, in *bxcore.SearchReq) bool {
 	if cc.PaySearchLimit.Switch && in.UserType != "fType" {
 		//首页----字数(<7)
@@ -693,6 +327,8 @@ func IsOptimize(cc config.Config, in *bxcore.SearchReq) bool {
 	}
 	return false
 }
+
+// GetPublishTime 查询时间调整
 func GetPublishTime(y, m int, publishTime string) string {
 	//发布时间
 	timeArray := strings.Split(publishTime, "-")
@@ -703,7 +339,9 @@ func GetPublishTime(y, m int, publishTime string) string {
 			if endTime == 0 {
 				endTime = time.Now().Unix()
 			}
+			//重新计算数据查询 开始时间
 			pTime := time.Unix(endTime, 0).AddDate(y, m, 0).Unix()
+			//从新定义搜索时间跨度
 			if endTime-startTime > pTime {
 				return fmt.Sprintf("%d-%d", pTime, endTime)
 			}