Просмотр исходного кода

Merge branch 'dev/v1.1.49_wjh' into feature/v1.1.49

* dev/v1.1.49_wjh:
  xg
  p490
  no message
  p490

# Conflicts:
#	jyBXSubscribe/api/bxsubscribe.api
#	jyBXSubscribe/api/internal/handler/routes.go
#	jyBXSubscribe/api/internal/types/types.go
#	jyBXSubscribe/rpc/bxsubscribe.proto
Jianghan 1 год назад
Родитель
Сommit
af96b065a0

+ 3 - 79
jyBXSubscribe/api/internal/types/types.go

@@ -1,91 +1,12 @@
 // Code generated by goctl. DO NOT EDIT.
 package types
 
-<<<<<<< HEAD
-type SubscribeReq struct {
-	AppId          string                 `header:"appId"`
-	UserId         string                 `header:"userId"`
-	EntId          string                 `header:"entId,optional"`
-	EntUserId      string                 `header:"entUserId,optional"`
-	DeptId         string                 `header:"deptId,optional"` //部门id
-	PageNum        int64                  `json:"pageNum,optional"`
-	PageSize       int64                  `json:"pageSize,optional"`
-	SelectTime     string                 `json:"selectTime,optional"`
-	Area           string                 `json:"area,optional"`
-	City           string                 `json:"city,optional"`
-	Industry       string                 `json:"industry,optional"`
-	BuyerClass     string                 `json:"buyerClass,optional"`
-	KeyWords       string                 `json:"keyWords,optional"`
-	Subtype        string                 `json:"subtype,optional"`
-	Price          string                 `json:"price,optional"`
-	FileExists     string                 `json:"fileExists,optional"`
-	Source         string                 `json:"source,optional"`                                        //信息来源
-	IsRead         string                 `json:"isRead,optional"`                                        //是否已读
-	Staffs         string                 `json:"staffs,optional"`                                        //分发的员工
-	UserType       string                 `path:"userType,default=fType,options=fType|vType|mType|eType"` //fType:普通用户;vType:超级订阅用户;mType:大会员用户;eType:商机管理用户;
-	NewUserId      int64                  `header:"newUserId"`
-	IsEnt          bool                   `json:"isEnt,optional"`
-	SelectIds      string                 `json:"selectIds,optional"`
-	SelectKeys     string                 `json:"selectKeys,optional"`
-	PositionType   int64                  `header:"positionType,optional"`
-	NotReturnCount int64                  `json:"notReturnCount,optional"`
-	Item           map[string]interface{} `json:"item,optional"`
-	AccountId      string                 `header:"accountId,optional"`
-	PositionId     string                 `header:"positionId,optional"`
-	MgoUserId      string                 `header:"mgoUserId,optional"` //原userId
-	District       string                 `json:"district,optional"`
-}
-
-type SomeInfoReq struct {
-	AppId        string `header:"appId"`
-	UserType     string `path:"userType"`
-	UserId       string `header:"userId,optional"`
-	NewUserId    string `header:"newUserId,optional"`
-	EntId        string `header:"entId,optional"`
-	AccountId    string `header:"accountId,optional"`
-	PositionType string `header:"positionType,optional"`
-	PositionId   string `header:"positionId,optional"`
-}
-
-type CommonResp struct {
-	Err_code int64       `json:"error_code"`
-	Err_msg  string      `json:"error_msg"`
-	Data     interface{} `json:"data"`
-	TimeData interface{} `json:"timeData"`
-}
-
-type SubscribeUpdateReq struct {
-	Area            map[string]interface{}   `json:"area,optional"`            //地区
-	Buyerclass      []string                 `json:"buyerclass,optional"`      //采购单位类型
-	Items           []map[string]interface{} `json:"items,optional"`           //关键词
-	Infotype        []string                 `json:"infotype,optional"`        //信息类型
-	Matchway        string                   `json:"matchway,optional"`        //匹配方式 1标题 2正文
-	Projectmatch    string                   `json:"projectmatch,optional"`    //项目匹配 1开始 0关闭
-	Ratemode        string                   `json:"ratemode,optional"`        // 1:实时推送,2:每天9点推送,3:每周推送,4:每月推送 5:每日推送两次
-	Apppush         string                   `json:"apppush,optional"`         //app推送 1开启 0关闭
-	Mailpush        string                   `json:"mailpush,optional"`        //邮箱推送 1开启 0关闭
-	Mail            string                   `json:"mail,optional"`            //邮箱
-	Otherbuyerclass string                   `json:"otherbuyerclass,optional"` //匹配未分类类型 1匹配 0不匹配
-	AppId           string                   `header:"appId,optional"`
-	UserType        string                   `path:"userType,optional"`
-	UserId          string                   `header:"userId,optional"`
-	PositionType    int64                    `header:"positionType,optional"`
-	NewUserId       int64                    `header:"newUserId,optional"`
-	EntId           int64                    `header:"entId,optional"`
-	AccountId       int64                    `header:"accountId,optional"`
-	PositionId      int64                    `header:"positionId,optional"`
-	District        map[string]interface{}   `json:"district,optional"`
-	ISwitch         int64                    `json:"iSwitch,optional"`
-	Amount          string                   `json:"amount,optional"`
-	Matchmode       string                   `json:"matchmode,optional"`
-=======
 type BidDistributor struct {
 	AppId     string   `header:"appId"`
 	EntId     string   `header:"entId,optional"`
 	EntUserId string   `header:"entUserId,optional"`
 	Infoids   []string `json:"infoids"`
 	Staffs    string   `json:"staffs"`
->>>>>>> master
 }
 
 type BidRecListReq struct {
@@ -279,6 +200,9 @@ type SubscribeUpdateReq struct {
 	AccountId       int64                    `header:"accountId,optional"`
 	PositionId      int64                    `header:"positionId,optional"`
 	District        map[string]interface{}   `json:"district,optional"`
+	ISwitch         int64                    `json:"iSwitch,optional"`
+	Amount          string                   `json:"amount,optional"`
+	Matchmode       string                   `json:"matchmode,optional"`
 }
 
 type ViewStatusReq struct {

+ 126 - 20
jyBXSubscribe/rpc/model/push.go

@@ -31,7 +31,7 @@ import (
 const (
 	pageSize            = 100
 	AllSubPushCacheSize = 200
-	query               = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","area","city", "publishtime", "s_subscopeclass", "subtype", "title", "toptype", "type", "buyerclass","bidamount","budget","projectname","buyer","bidopentime","s_winner","filetext","spidercode","site","buyertel","buyerperson","agency","agencyperson","agencytel","winnerperson","winnertel","signendtime","bidendtime","entidlist","isValidFile"],"from":0,"size":%d}`
+	query               = `{"query":{"terms":{"_id":["%s"]}},"_source":["_id","area","city", "publishtime", "s_subscopeclass", "subtype", "title", "toptype", "type", "buyerclass","bidamount","budget","projectname","buyer","bidopentime","s_winner","filetext","spidercode","site","buyertel","buyerperson","agency","agencyperson","agencytel","winnerperson","winnertel","signendtime","bidendtime","entidlist","isValidFile", "detail"],"from":0,"size":%d}`
 	mongodb_fields      = `{"_id":1,"area":1,"publishtime":1,"s_subscopeclass":1,"subtype":1,"title":1,"toptype":1,"type":1, "city":1,"buyerclass":1,"budget":1,"bidamount":1,"s_winner":1,"bidopentime":1,"buyer":1,"projectname":1,"filetext":1,"spidercode":1,"site":1,"buyertel":1,"buyerperson":1,"agency":1,"agencyperson":1,"agencytel":1,"winnerperson":1,"winnertel":1,"signendtime":1,"bidendtime":1,"entidlist":1,"isValidFile":1}`
 
 	SubFreeFlag  = "fType"
@@ -519,6 +519,14 @@ func (s *subscribePush) inactiveQuery(spqp *SubPushQueryParam, bsp *ViewConditio
 	}
 	return array, count
 }
+
+var topTypeMap = map[string]string{
+	"招标预告":   "预告",
+	"招标公告":   "招标",
+	"招标结果":   "结果",
+	"招标信用信息": "其它",
+}
+
 func (s *subscribePush) getDatasFromMysql(spqp *SubPushQueryParam, starttime, endtime int64, size int, isLimit bool) (result []*bxsubscribe.SubscribeInfo, count int64) {
 	start := time.Now().Unix()
 	querys := []string{}
@@ -622,15 +630,52 @@ func (s *subscribePush) getDatasFromMysql(spqp *SubPushQueryParam, starttime, en
 		}
 		//信息类型
 		if spqp.Subtype != "" {
-			subtype := []string{}
-			for _, v := range strings.Split(spqp.Subtype, ",") {
-				subtype = append(subtype, P.BidCodeMapping.Subtype[v])
+			var topType []string
+			typeInt := 0
+			stype := strings.Split(spqp.Subtype, ",")
+			for _, v := range stype {
+				if tType := topTypeMap[v]; tType != "" {
+					topType = append(topType, tType)
+					typeInt += 1
+					continue
+				}
 			}
-			if len(subtype) == 1 {
-				subtype = append(subtype, "9999")
+			var subtype []string
+			var toptype []string
+			//subtype里都是二级级信息类型
+			if typeInt == 0 {
+				for _, v := range stype {
+					subtype = append(subtype, P.BidCodeMapping.Subtype[v])
+				}
+				if len(subtype) == 1 {
+					subtype = append(subtype, "9999")
+				}
+			} else if typeInt == len(stype) { // subtype里边 都是一级信息类型
+				for _, v := range topType {
+					toptype = append(toptype, P.BidCodeMapping.Toptype[v])
+				}
+				if len(subtype) == 1 {
+					toptype = append(toptype, "9999")
+				}
+			} else {
+				for _, v := range stype {
+					subtype = append(subtype, P.BidCodeMapping.Subtype[v])
+				}
+				if len(subtype) == 1 {
+					subtype = append(subtype, "9999")
+				}
+				for _, v := range topType {
+					toptype = append(toptype, P.BidCodeMapping.Toptype[v])
+				}
+				if len(subtype) == 1 {
+					toptype = append(toptype, "9999")
+				}
 			}
 			if len(subtype) > 0 {
-				querys = append(querys, fmt.Sprintf("subtype in (%s)", strings.Join(subtype, ",")))
+				querys = append(querys, fmt.Sprintf("a.subtype in (%s)", strings.Join(subtype, ",")))
+			}
+			if len(toptype) > 0 {
+				querys = append(querys, fmt.Sprintf("a.toptype in (%s)", strings.Join(toptype, ",")))
 			}
 		}
 		//信息行业
@@ -975,7 +1020,7 @@ func (s *subscribePush) GetJyPushs(datas []map[string]interface{}) (pushCas []*P
 
 // 查看全部列表缓存
 func (s *subscribePush) PutAllCache(userId, userType string, datas *SubPush) {
-	log.Println("pushcache_2_a", s.allKey(userId, userType), datas, oneDay)
+	//log.Println("pushcache_2_a", s.allKey(userId, userType), datas, oneDay)
 	redis.Put("pushcache_2_a", s.allKey(userId, userType), datas, oneDay)
 }
 
@@ -1176,7 +1221,7 @@ func GetKeySet(t string, u *map[string]interface{}, data []string) (bool, []stri
 const (
 	INDEX      = "bidding"
 	TYPE       = "bidding"
-	bidField   = `"_id","title","publishtime","toptype","subtype","type","area","city","s_subscopeclass","buyerclass","budget","bidamount","filetext","spidercode","site","buyer","bidopentime","buyertel","buyerperson","agency","agencyperson","agencytel","s_winner","winnerperson","winnertel","signendtime","bidendtime","entidlist"`
+	bidField   = `"_id","title","publishtime","toptype","subtype","type","area","city","s_subscopeclass","buyerclass","budget","bidamount","filetext","spidercode","site","buyer","bidopentime","buyertel","buyerperson","agency","agencyperson","agencytel","s_winner","winnerperson","winnertel","signendtime","bidendtime","entidlist", "detail"`
 	bidTime    = `{"range":{"publishtime":{"gt":%d}}}`
 	bidSort    = `{"publishtime":"desc"}`
 	findfields = `"title"`
@@ -1416,15 +1461,42 @@ func (s *subscribePush) getFreeDatasSQL(bsp *ViewCondition, startTime, endTime i
 		Buyerclass += `]}}`
 		musts = append(musts, Buyerclass)
 	}
+	/**
+	  100-500
+	  100-
+	  -500
+	*/
+	if bsp.Amount != "" {
+		at := strings.Split(bsp.Amount, "-")
+		if len(at) == 2 {
+			Bidamount := `{"range":{"bidamount":{` // "gte": %d, "lte": %d}}}
+			if at[0] != "" {
+				minPrice := common.Int64All(common.Float64All(at[0]) * 10000) //换成元
+				if minPrice >= 0 {
+					Bidamount += fmt.Sprintf("\"gte\": %d", minPrice)
+				}
+			}
+			if at[1] != "" {
+				maxPrice := common.Int64All(common.Float64All(at[1]) * 10000)
+				if maxPrice > 0 {
+					Bidamount += fmt.Sprintf(",\"lte\": %d", maxPrice)
+				}
+			}
+			Bidamount += `}}}`
+			musts = append(musts, Bidamount)
+		}
+
+	}
 	boolsNum := 0 //should
 	if len(bsp.Keyword) > 0 {
 		boolsNum = 1
-		if bsp.SelectType == "" || bsp.SelectType == "2" {
-			bsp.SelectType = "detail\", \"title"
+		stype := ""
+		if len(bsp.SelectType) == 1 {
+			stype = bsp.SelectType[0]
 		} else {
-			bsp.SelectType = "title"
+			stype = strings.Join(bsp.SelectType, "\",\"")
 		}
-		multi_match = fmt.Sprintf(multi_match, "%s", "\""+bsp.SelectType+"\"")
+		multi_match = fmt.Sprintf(multi_match, "%s", "\""+stype+"\"")
 		for _, v := range bsp.Keyword {
 			shoulds := []string{}
 			must_not := []string{}
@@ -1544,12 +1616,13 @@ func (s *subscribePush) getDefaultDatasSQL(bsp *ViewCondition) (str string) {
 	boolsNum := 0 //should
 	if len(bsp.Keyword) > 0 {
 		boolsNum = 1
-		if bsp.SelectType == "" || bsp.SelectType == "2" {
-			bsp.SelectType = "detail\", \"title"
+		stype := ""
+		if len(bsp.SelectType) == 1 {
+			stype = bsp.SelectType[0]
 		} else {
-			bsp.SelectType = "title"
+			stype = strings.Join(bsp.SelectType, "\",\"")
 		}
-		multi_match = fmt.Sprintf(multi_match, "%s", "\""+bsp.SelectType+"\"")
+		multi_match = fmt.Sprintf(multi_match, "%s", "\""+stype+"\"")
 		for _, v := range bsp.Keyword {
 			shoulds := []string{}
 			must_not := []string{}
@@ -1610,9 +1683,10 @@ type ViewCondition struct {
 	District   []string      //区县
 	Buyerclass []string      //采购行业
 	Keyword    []ViewKeyWord //关键词
-	SelectType string        //筛选(正文 or 标题)
+	SelectType []string      //筛选(正文 or 标题)
 	Subtype    []string      //信息类型
 	Size       int           //数量
+	Amount     string        //金额
 }
 
 // 获取用户信息
@@ -1624,7 +1698,8 @@ func (s *subscribePush) GetUserInfo(spqp *SubPushQueryParam) (vc *ViewCondition)
 		SubType    []interface{}
 		Area       map[string]interface{}
 		District   map[string]interface{}
-		SelectType string
+		SelectType []string
+		Amount     string
 	}{}
 	switch s.ModuleFlag {
 	case MemberFlag:
@@ -1642,6 +1717,12 @@ func (s *subscribePush) GetUserInfo(spqp *SubPushQueryParam) (vc *ViewCondition)
 			tmpInfo.SubType, _ = o_member_jy["a_infotype"].([]interface{})
 			tmpInfo.Area, _ = o_member_jy["o_area"].(map[string]interface{})
 			tmpInfo.District, _ = o_member_jy["o_district"].(map[string]interface{})
+			if o_member_jy["i_matchmode"] != nil {
+				tmpInfo.SelectType = o_member_jy["i_matchmode"].([]string)
+			} else {
+				tmpInfo.SelectType = []string{"title"}
+			}
+			tmpInfo.Amount = common.ObjToString(o_member_jy["amount"])
 		}
 	case SubVipFlag:
 		userMap, ok := IC.Mgo.FindById("user", spqp.UserId, `{"o_vipjy":1,"i_vip_status":1,"subpush_inactive":1}`)
@@ -1657,6 +1738,12 @@ func (s *subscribePush) GetUserInfo(spqp *SubPushQueryParam) (vc *ViewCondition)
 			tmpInfo.SubType, _ = o_vipjy["a_infotype"].([]interface{})
 			tmpInfo.Area, _ = o_vipjy["o_area"].(map[string]interface{})
 			tmpInfo.District, _ = o_vipjy["o_district"].(map[string]interface{})
+			if o_vipjy["i_matchmode"] != nil {
+				tmpInfo.SelectType = o_vipjy["i_matchmode"].([]string)
+			} else {
+				tmpInfo.SelectType = []string{"title"}
+			}
+			tmpInfo.Amount = common.ObjToString(o_vipjy["amount"])
 		}
 	case EntnicheFlag:
 		//商机管理
@@ -1673,6 +1760,12 @@ func (s *subscribePush) GetUserInfo(spqp *SubPushQueryParam) (vc *ViewCondition)
 					//省份
 					tmpInfo.Area, _ = entInfo["o_area"].(map[string]interface{})
 					tmpInfo.District, _ = entInfo["o_district"].(map[string]interface{})
+					if entInfo["i_matchmode"] != nil {
+						tmpInfo.SelectType = entInfo["i_matchmode"].([]string)
+					} else {
+						tmpInfo.SelectType = []string{"title"}
+					}
+					tmpInfo.Amount = common.ObjToString(entInfo["amount"])
 					if common.IntAllDef(entInfo["i_ppstatus"], 0) == 1 && entInfo["o_area_p"] != nil {
 						tmpInfo.Area, _ = entInfo["o_area_p"].(map[string]interface{})
 					}
@@ -1684,6 +1777,12 @@ func (s *subscribePush) GetUserInfo(spqp *SubPushQueryParam) (vc *ViewCondition)
 				tmpInfo.SubType, _ = entInfo["a_infotype"].([]interface{})
 				tmpInfo.Area, _ = entInfo["o_area"].(map[string]interface{})
 				tmpInfo.District, _ = entInfo["o_district"].(map[string]interface{})
+				if entInfo["i_matchmode"] != nil {
+					tmpInfo.SelectType = entInfo["i_matchmode"].([]string)
+				} else {
+					tmpInfo.SelectType = []string{"title"}
+				}
+				tmpInfo.Amount = common.ObjToString(entInfo["amount"])
 			}
 		}
 	default:
@@ -1700,6 +1799,12 @@ func (s *subscribePush) GetUserInfo(spqp *SubPushQueryParam) (vc *ViewCondition)
 			//省份
 			tmpInfo.Area, _ = o_jy["o_area"].(map[string]interface{})
 			tmpInfo.District, _ = o_jy["o_district"].(map[string]interface{})
+			if o_jy["i_matchmode"] != nil {
+				tmpInfo.SelectType = o_jy["i_matchmode"].([]string)
+			} else {
+				tmpInfo.SelectType = []string{"title"}
+			}
+			tmpInfo.Amount = common.ObjToString(o_jy["amount"])
 			if common.IntAllDef(o_jy["i_ppstatus"], 0) == 1 && o_jy["o_area_p"] != nil {
 				tmpInfo.Area, _ = o_jy["o_area_p"].(map[string]interface{})
 			}
@@ -1711,7 +1816,8 @@ func (s *subscribePush) GetUserInfo(spqp *SubPushQueryParam) (vc *ViewCondition)
 		Area:       getStringArrFromDbResult(tmpInfo.Area, 1),
 		City:       getStringArrFromDbResult(tmpInfo.Area, 2),
 		District:   districtHandle(tmpInfo.District),
-		SelectType: "1",
+		SelectType: tmpInfo.SelectType,
+		Amount:     tmpInfo.Amount,
 	}
 	//付费用户
 	if isPayBool {

+ 8 - 96
jyBXSubscribe/rpc/type/bxsubscribe/bxsubscribe.pb.go

@@ -3363,6 +3363,7 @@ type PushSet struct {
 	IRatemode   int64    `protobuf:"varint,5,opt,name=i_ratemode,json=iRatemode,proto3" json:"i_ratemode,omitempty"`
 	IsWxShow    int64    `protobuf:"varint,6,opt,name=isWxShow,proto3" json:"isWxShow,omitempty"`
 	Interested  int64    `protobuf:"varint,7,opt,name=interested,proto3" json:"interested,omitempty"`
+	IsMailShow  int64    `protobuf:"varint,8,opt,name=isMailShow,proto3" json:"isMailShow,omitempty"`
 	INomsgtip   int64    `protobuf:"varint,9,opt,name=i_nomsgtip,json=iNomsgtip,proto3" json:"i_nomsgtip,omitempty"`
 	IApppushTip int64    `protobuf:"varint,10,opt,name=i_apppush_tip,json=iApppushTip,proto3" json:"i_apppush_tip,omitempty"`
 }
@@ -3448,6 +3449,13 @@ func (x *PushSet) GetInterested() int64 {
 	return 0
 }
 
+func (x *PushSet) GetIsMailShow() int64 {
+	if x != nil {
+		return x.IsMailShow
+	}
+	return 0
+}
+
 func (x *PushSet) GetINomsgtip() int64 {
 	if x != nil {
 		return x.INomsgtip
@@ -4572,105 +4580,9 @@ var file_bxsubscribe_proto_rawDesc = []byte{
 	0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65,
 	0x72, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54,
 	0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x6f, 0x73, 0x69, 0x74,
-<<<<<<< HEAD
-	0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x61, 0x73, 0x65, 0x55,
-	0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x61, 0x73,
-	0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x7b, 0x0a, 0x0f, 0x47, 0x65, 0x74,
-	0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x71, 0x12, 0x2c, 0x0a, 0x04,
-	0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x78, 0x73,
-	0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
-	0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72,
-	0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65,
-	0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72,
-	0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x65, 0x72, 0x72,
-	0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x7f, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
-	0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61,
-	0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12,
-	0x16, 0x0a, 0x06, 0x69, 0x6d, 0x67, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x06, 0x69, 0x6d, 0x67, 0x55, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x55, 0x72,
-	0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x70, 0x70, 0x55, 0x72, 0x6c, 0x12,
-	0x16, 0x0a, 0x06, 0x73, 0x68, 0x6f, 0x77, 0x57, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52,
-	0x06, 0x73, 0x68, 0x6f, 0x77, 0x57, 0x78, 0x22, 0xaa, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x55,
-	0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 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, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
-	0x05, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65,
-	0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x55, 0x73,
-	0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c,
-	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01,
-	0x28, 0x03, 0x52, 0x0c, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65,
-	0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x6d, 0x61, 0x69, 0x6c, 0x22, 0x91, 0x02, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68,
-	0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05,
-	0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x65, 0x6e, 0x74,
-	0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64,
-	0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x6f, 0x73, 0x69,
-	0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c,
-	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a,
-	0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03,
-	0x52, 0x0a, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09,
-	0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52,
-	0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x61,
-	0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a,
-	0x62, 0x61, 0x73, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x67,
-	0x6f, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d,
-	0x67, 0x6f, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0xf1, 0x02, 0x0a, 0x0e, 0x47, 0x65, 0x74,
-	0x50, 0x75, 0x73, 0x68, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, 0x04, 0x64,
-	0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x62, 0x78, 0x73, 0x75,
-	0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x53,
-	0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
-	0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x61,
-	0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x62, 0x78, 0x73, 0x75, 0x62,
-	0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x53, 0x65,
-	0x74, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e,
-	0x74, 0x72, 0x79, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a,
-	0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72,
-	0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
-	0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0x4d, 0x0a, 0x09, 0x44, 0x61, 0x74,
-	0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x78, 0x73, 0x75, 0x62, 0x73,
-	0x63, 0x72, 0x69, 0x62, 0x65, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x65, 0x74, 0x52, 0x05, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x52, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65,
-	0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x78, 0x73,
-	0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x4a, 0x73, 0x6f,
-	0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x23, 0x0a, 0x08,
-	0x54, 0x69, 0x6d, 0x65, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x61, 0x5f, 0x74, 0x69,
-	0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x61, 0x54, 0x69, 0x6d, 0x65,
-	0x73, 0x22, 0x97, 0x02, 0x0a, 0x07, 0x50, 0x75, 0x73, 0x68, 0x53, 0x65, 0x74, 0x12, 0x17, 0x0a,
-	0x07, 0x61, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
-	0x61, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x5f, 0x77, 0x78, 0x70, 0x75,
-	0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x69, 0x57, 0x78, 0x70, 0x75, 0x73,
-	0x68, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x5f, 0x61, 0x70, 0x70, 0x70, 0x75, 0x73, 0x68, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x69, 0x41, 0x70, 0x70, 0x70, 0x75, 0x73, 0x68, 0x12, 0x1d,
-	0x0a, 0x0a, 0x69, 0x5f, 0x6d, 0x61, 0x69, 0x6c, 0x70, 0x75, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x03, 0x52, 0x09, 0x69, 0x4d, 0x61, 0x69, 0x6c, 0x70, 0x75, 0x73, 0x68, 0x12, 0x1d, 0x0a,
-	0x0a, 0x69, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
-	0x03, 0x52, 0x09, 0x69, 0x52, 0x61, 0x74, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08,
-	0x69, 0x73, 0x57, 0x78, 0x53, 0x68, 0x6f, 0x77, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08,
-	0x69, 0x73, 0x57, 0x78, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 0x74, 0x65,
-	0x72, 0x65, 0x73, 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x69, 0x6e,
-	0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x5f, 0x6e, 0x6f,
-	0x6d, 0x73, 0x67, 0x74, 0x69, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x69, 0x4e,
-	0x6f, 0x6d, 0x73, 0x67, 0x74, 0x69, 0x70, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x5f, 0x61, 0x70, 0x70,
-	0x70, 0x75, 0x73, 0x68, 0x5f, 0x74, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b,
-	0x69, 0x41, 0x70, 0x70, 0x70, 0x75, 0x73, 0x68, 0x54, 0x69, 0x70, 0x22, 0xcf, 0x02, 0x0a, 0x0d,
-	0x53, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a,
-=======
 	0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x18,
 	0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x91, 0x02, 0x0a, 0x0d,
 	0x47, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a,
->>>>>>> master
 	0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70,
 	0x70, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01,
 	0x28, 0x03, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x74,