ソースを参照

Merge branch 'dev/v1.2.11_fuwencai' of moapp/MessageCenter into feature/v1.2.11

fuwencai 1 年間 前
コミット
76375374d7

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+/.output/
+.idea

+ 0 - 8
.idea/.gitignore

@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
-# Editor-based HTTP Client requests
-/httpRequests/

+ 0 - 9
.idea/MessageCenter.iml

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="WEB_MODULE" version="4">
-  <component name="Go" enabled="true" />
-  <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$" />
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>

+ 0 - 42
.idea/deployment.xml

@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="PublishConfigData" remoteFilesAllowedToDisappearOnAutoupload="false">
-    <serverData>
-      <paths name="1.117.171.133">
-        <serverdata>
-          <mappings>
-            <mapping local="$PROJECT_DIR$" web="/" />
-          </mappings>
-        </serverdata>
-      </paths>
-      <paths name="192.168.3.11">
-        <serverdata>
-          <mappings>
-            <mapping local="$PROJECT_DIR$" web="/" />
-          </mappings>
-        </serverdata>
-      </paths>
-      <paths name="192.168.3.204">
-        <serverdata>
-          <mappings>
-            <mapping local="$PROJECT_DIR$" web="/" />
-          </mappings>
-        </serverdata>
-      </paths>
-      <paths name="192.168.3.206">
-        <serverdata>
-          <mappings>
-            <mapping local="$PROJECT_DIR$" web="/" />
-          </mappings>
-        </serverdata>
-      </paths>
-      <paths name="192.168.3.240">
-        <serverdata>
-          <mappings>
-            <mapping local="$PROJECT_DIR$" web="/" />
-          </mappings>
-        </serverdata>
-      </paths>
-    </serverData>
-  </component>
-</project>

+ 0 - 8
.idea/modules.xml

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/MessageCenter.iml" filepath="$PROJECT_DIR$/.idea/MessageCenter.iml" />
-    </modules>
-  </component>
-</project>

+ 0 - 6
.idea/vcs.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$" vcs="Git" />
-  </component>
-</project>

+ 1 - 1
README.md

@@ -1,4 +1,4 @@
 消息中台
-goctl rpc proto -src message.proto -dir .goctl rpc protoc message.proto --go_out=./type --go-grpc_out=./type --zrpc_out=.
+goctl rpc protoc message.proto --go_out=./type --go-grpc_out=./type --zrpc_out=.
 goctl api go -api message.api -dir .
 

+ 2 - 0
api/internal/logic/messagelistlogic.go

@@ -42,6 +42,7 @@ func (l *MessageListLogic) MessageList(req *types.MessageListReq) (resp *types.M
 		PositionId:      req.PositionId,
 		NewUserId:       req.NewUserId,
 		IsContainLetter: req.IsContainLetter,
+		IsClassSearch:   req.IsClassSearch,
 	})
 	if err != nil {
 		return nil, err
@@ -98,6 +99,7 @@ func (l *MessageListLogic) MessageList(req *types.MessageListReq) (resp *types.M
 				"img":            vs.Img,
 				"msg_type":       vs.MsgType,
 				"unreadMessages": vs.UnreadMessages,
+				"isClassSearch":  vs.IsClassSearch,
 			}
 			var cn []map[string]interface{}
 			for _, v := range vs.Data {

+ 1 - 0
api/internal/types/types.go

@@ -100,6 +100,7 @@ type MessageListReq struct {
 	IsColumnNewMsg  bool   `json:"isColumnNewMsg"`                        //是否需各栏目获取最新消息
 	IsMsgList       bool   `json:"isMsgList"`                             //是否需要列表信息
 	IsContainLetter bool   `json:"isContainLetter,optional,default=true"` //是否未读数包含私信
+	IsClassSearch   bool   `json:"isClassSearch,optional"`                // 是否为具体分类查询
 }
 
 type MessageListResp struct {

+ 1 - 0
api/message.api

@@ -104,6 +104,7 @@ type MessageListReq {
 	IsColumnNewMsg  bool   `json:"isColumnNewMsg"`                        //是否需各栏目获取最新消息
 	IsMsgList       bool   `json:"isMsgList"`                             //是否需要列表信息
 	IsContainLetter bool   `json:"isContainLetter,optional,default=true"` //是否未读数包含私信
+	IsClassSearch   bool   `json:"isClassSearch,optional"`                // 是否为具体分类查询
 }
 
 type MessageListResp {

+ 6 - 0
entity/message.go

@@ -19,7 +19,13 @@ var GmailAuth []*mail.GmailAuth
 var SurvivalTime int
 var RollingTiming int64
 var SaveConcurrencyChan chan int //  定义保存消息并发
+var ClassSearchMap map[int64][]MsgClass
 
+type MsgClass struct {
+	MsgType int64  `json:"msgType"`
+	Name    string `json:"name"`
+	Img     string `json:"img"`
+}
 type Message struct {
 	Id            string    `xorm:"id" form:"id" json:"id"`
 	AppId         string    `xorm:"appid" form:"appid" json:"appid"`

+ 2 - 0
rpc/etc/message.yaml

@@ -64,3 +64,5 @@ WxTmplConfig:
       toMail: [ "wangkaiyue@topnet.net.cn" ] #告警邮箱收件地址
       ccMail: [ "duxin@topnet.net.cn" ] #告警邮箱抄送地址
 Tidb: "root:=PDT49#80Z!RVv52_z@tcp(192.168.3.217:4000)/messagetest?charset=utf8mb4&parseTime=true&loc=Local"
+ClassSearchList: # 需要按照messageClass 查询的groupId
+  - 11  # 待办 group id

+ 8 - 0
rpc/internal/common/getBuoyMsg.go

@@ -5,6 +5,7 @@ import (
 	"app.yhyue.com/moapp/MessageCenter/rpc/type/message"
 	"app.yhyue.com/moapp/MessageCenter/util"
 	qutil "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/redis"
 	"fmt"
 	"log"
 	"strconv"
@@ -78,6 +79,13 @@ func ClearUnreadMsg(in *message.ClearUnreadMsgReq) error {
 		if !entity.Mysql.Update("message", query, map[string]interface{}{"isRead": 1}) {
 			log.Println("更新服务未读数失败")
 		}
+		// p436  清空消息时  "msg_class_count_%s_%d" 下的消息数量也清空
+		for _, classes := range entity.ClassSearchMap {
+			for i := 0; i < len(classes); i++ {
+				classKeyString := fmt.Sprintf(MsgClassCountKey, in.Userid, classes[i].MsgType)
+				redis.Put(redisModule, classKeyString, 0, -1)
+			}
+		}
 		for _, v := range entity.MessageColumn {
 			go MsgCountZero(in.Userid, in.AppId, qutil.Int64All(v["group_id"]))
 		}

+ 46 - 0
rpc/internal/common/messageClass.go

@@ -0,0 +1,46 @@
+package common
+
+import (
+	"app.yhyue.com/moapp/MessageCenter/entity"
+	"app.yhyue.com/moapp/MessageCenter/rpc/internal/config"
+	"app.yhyue.com/moapp/jybase/common"
+	"fmt"
+	"strings"
+)
+
+// InitClassSearchMap 初始化需要展示细化分类的消息分类信息
+func InitClassSearchMap() {
+	entity.ClassSearchMap = map[int64][]entity.MsgClass{}
+	// 初始化需要展示消息细化分类的groupid 和对应的class信息
+	if config.ConfigJson.ClassSearchList != nil && len(config.ConfigJson.ClassSearchList) > 0 {
+		groupIDs := config.ConfigJson.ClassSearchList
+		qArr := []string{}
+		for i := 0; i < len(groupIDs); i++ {
+			qArr = append(qArr, fmt.Sprintf("%d", groupIDs[i]))
+		}
+		// 查库
+		q := "SELECT * FROM message_class where group_id in (" + strings.Join(qArr, ",") + ") order by msg_type;"
+		rs := entity.Mysql.SelectBySql(q)
+		if rs != nil && len(*rs) > 0 {
+			for i := 0; i < len(*rs); i++ {
+				groupID := common.Int64All((*rs)[i]["group_id"])
+				msgName := common.ObjToString((*rs)[i]["msg_name"])
+				msgType := common.Int64All((*rs)[i]["msg_type"])
+				img := common.ObjToString((*rs)[i]["img"])
+				// 处理成map
+				if _, ok := entity.ClassSearchMap[groupID]; !ok {
+					entity.ClassSearchMap[groupID] = []entity.MsgClass{}
+				}
+				entity.ClassSearchMap[groupID] = append(entity.ClassSearchMap[groupID], entity.MsgClass{
+					MsgType: msgType,
+					Name:    msgName,
+					Img:     img,
+				})
+			}
+		}
+	}
+}
+
+//func ()  {
+//
+//}

+ 31 - 1
rpc/internal/common/messageService.go

@@ -26,7 +26,7 @@ func (service *MessageService) ChangeReadStatus(data *message.ChangeReadStatusRe
 	if !b {
 		return 0, "修改消息阅读状态失败"
 	}
-	MsgCountMinusOne(qutil.ObjToString((*msg)["receive_userid"]), data.Appid, qutil.Int64All((*msg)["group_id"]))
+	MsgCountMinusOne(qutil.ObjToString((*msg)["receive_userid"]), data.Appid, qutil.Int64All((*msg)["group_id"]), qutil.Int64All((*msg)["msg_type"]))
 	return 1, "修改消息阅读状态成功"
 }
 
@@ -101,6 +101,36 @@ func (service *MessageService) CountUnread(userId string, isRedis bool) (map[str
 
 	return data, count
 }
+func (service *MessageService) CountClassUnread(userId string, groupId int64) (classCount map[string]int64, total int64) {
+	var (
+		count int64
+	)
+	data := make(map[string]int64)
+	if _, ok := entity.ClassSearchMap[groupId]; !ok {
+		return
+	}
+	for i := 0; i < len(entity.ClassSearchMap[groupId]); i++ {
+		msgClass := entity.ClassSearchMap[groupId][i]
+		key := fmt.Sprintf(MsgClassCountKey, userId, msgClass.MsgType)
+		if exists, _ := redis.Exists(redisModule, key); exists {
+			ct := util.Int64All(redis.GetInt(redisModule, key))
+			data[fmt.Sprintf("%d", msgClass.MsgType)] = ct
+			count += ct
+		} else {
+			q := "select count(*) from message where receive_userid=? and isdel=1 and msg_type=?"
+			classCount := entity.Mysql.CountBySql(q, userId, msgClass.MsgType)
+			if classCount != -1 {
+				redis.Put(redisModule, key, classCount, -1)
+				data[fmt.Sprintf("%d", msgClass.MsgType)] = classCount
+				count += classCount
+			} else {
+				log.Println("查询classCount失败:", classCount, q)
+			}
+		}
+	}
+
+	return data, count
+}
 
 // 查询消息详情
 func FindMessageDetail(id, msgLogId int64, userId string) (msg *map[string]interface{}, err error) {

+ 58 - 8
rpc/internal/common/sendMsg.go

@@ -18,7 +18,8 @@ import (
 
 // 类型的顺序
 const order = "1,4"
-const MsgCountKey = "count_%s_%d" //redis 消息未读数量 Count.用户id.消息类型=数量
+const MsgCountKey = "count_%s_%d"                //redis 消息未读数量 Count.用户id.消息类型=数量
+const MsgClassCountKey = "msg_class_count_%s_%d" //redis 用户消息class分类消息数量
 const redisModule = "msgCount"
 
 func FindUserMsg(this message.FindUserMsgReq, isClean bool) message.FindUserMsgRes {
@@ -116,7 +117,10 @@ func UserMsgList(this *message.UserMsgListReq) *message.UserMsgList {
 		"isdel":          1,
 		"appid":          this.Appid,
 	}
-	if this.MsgType > 0 {
+	// p436 细化分类时需要用msg_type 进行查询
+	if this.MsgType > 0 && this.IsClassSearch {
+		cquery["msg_type"] = this.MsgType
+	} else if this.MsgType > 0 {
 		cquery["group_id"] = this.MsgType
 	}
 	if this.Read != -1 {
@@ -127,12 +131,23 @@ func UserMsgList(this *message.UserMsgListReq) *message.UserMsgList {
 	sData := make(map[string][]*message.Messages)
 	t := time.Now()
 	if this.IsColumnNewMsg && this.SortSize > 0 {
-		sortData := entity.Mysql.SelectBySql(fmt.Sprintf(`SELECT title,createtime,group_id,id FROM (
+		var sortData *[]map[string]interface{}
+		if this.IsClassSearch { // p436 增加
+			sortDataQ := fmt.Sprintf(`SELECT title,createtime,msg_type as group_id ,id FROM (
+  			SELECT title,createtime,msg_type,id, ROW_NUMBER() OVER (PARTITION BY msg_type, receive_userid ORDER BY createtime DESC) AS row_num
+  			FROM message
+  			WHERE receive_userid = '%s' and isdel = 1 and  appid = %s and  group_id=%d
+		) AS message_ranked
+		WHERE row_num <=%d;`, this.UserId, this.Appid, this.MsgType, this.SortSize)
+			sortData = entity.Mysql.SelectBySql(sortDataQ)
+		} else {
+			sortData = entity.Mysql.SelectBySql(fmt.Sprintf(`SELECT title,createtime,group_id,id FROM (
   			SELECT title,createtime,group_id,id, ROW_NUMBER() OVER (PARTITION BY group_id, receive_userid ORDER BY createtime DESC) AS row_num
   			FROM message
   			WHERE receive_userid = '%s' and isdel = 1 and  appid = %s
 		) AS message_ranked
 		WHERE row_num <=%d;`, this.UserId, this.Appid, this.SortSize))
+		}
 		log.Println("消息列表耗时1:", time.Since(t))
 		if sortData != nil {
 			for _, v := range *sortData {
@@ -152,9 +167,29 @@ func UserMsgList(this *message.UserMsgListReq) *message.UserMsgList {
 			}
 		}
 	}
-	//消息栏目下的最新消息
+	// 消息栏目下的最新消息
 	var columnData []*message.AllSortData
-	if this.IsColumn {
+	if this.IsColumn && this.MsgType > 0 && this.IsClassSearch {
+		// p436 处理消息细分分类要返回的数据
+		// 获取小分类下的未读数
+		sortUnread, _ := m.CountClassUnread(this.UserId, this.MsgType)
+		columnMap := entity.ClassSearchMap[this.MsgType]
+		for i := 0; i < len(columnMap); i++ {
+			tmp := columnMap[i]
+			var column message.AllSortData
+			column.Name = tmp.Name
+			column.Img = fmt.Sprintf("/common-module/msgCenter/%s.png", tmp.Img)
+			column.MsgType = tmp.MsgType
+			// 消息未读数
+			msgType := common.InterfaceToStr(tmp.MsgType)
+			column.UnreadMessages = sortUnread[msgType]
+			unread += sortUnread[msgType]
+			column.Data = sData[msgType]
+			column.IsClassSearch = true
+			columnData = append(columnData, &column)
+		}
+		// 未读数量
+	} else if this.IsColumn {
 		//获取所有分类未读数 不初始化
 		sortUnread, _ := m.CountUnread(this.UserId, false)
 		for _, v := range entity.MessageColumn {
@@ -171,6 +206,11 @@ func UserMsgList(this *message.UserMsgListReq) *message.UserMsgList {
 				unread += sortUnread[msgType]
 				column.Data = sData[msgType]
 			}
+			// p436  该groupId属于展示细化分类的  如待办 点击待办进入到待参加会议、待处理任务中间列表页等
+			// 该返回值用于前端后续传参使用
+			if _, ok := entity.ClassSearchMap[column.MsgType]; ok {
+				column.IsClassSearch = true
+			}
 			columnData = append(columnData, &column)
 		}
 	}
@@ -332,8 +372,12 @@ func MessageGetLast(this *message.UserMsgListReq) *message.Messages {
 }
 
 // MsgCountAdd 消息未读数量加1
-func MsgCountAdd(userId, appId string, msgType int64) bool {
+func MsgCountAdd(userId, appId string, msgType int64, msgClassType int64) bool {
 	keyString := fmt.Sprintf(MsgCountKey, userId, msgType)
+	classKeyString := fmt.Sprintf(MsgClassCountKey, userId, msgClassType)
+	if exist, _ := redis.Exists(redisModule, classKeyString); exist {
+		redis.Incr(redisModule, classKeyString)
+	}
 	exists, _ := redis.Exists(redisModule, keyString)
 	if exists {
 		in := redis.Incr(redisModule, keyString)
@@ -351,7 +395,13 @@ func MsgCountAdd(userId, appId string, msgType int64) bool {
 }
 
 // MsgCountMinusOne 根据消息类型未读消息数量减1
-func MsgCountMinusOne(userId, appId string, msgType int64) bool {
+func MsgCountMinusOne(userId, appId string, msgType int64, msgClassType int64) bool {
+	classKeyString := fmt.Sprintf(MsgClassCountKey, userId, msgClassType)
+	if exist, _ := redis.Exists(redisModule, classKeyString); exist {
+		if redis.GetInt(redisModule, MsgClassCountKey) > 0 {
+			redis.Decrby(redisModule, classKeyString, 1)
+		}
+	}
 	keyString := fmt.Sprintf(MsgCountKey, userId, msgType)
 	exists, _ := redis.Exists(redisModule, keyString)
 	if exists {
@@ -449,7 +499,7 @@ func MultSave(this message.MultipleSaveMsgReq) (int64, string) {
 			in = entity.Mysql.InsertBySql(sql3, common.If(positionId != 0, positionId, nil))
 			logx.Info("插入消息返回 in1 id:", in, "消息类型:", this.MsgType, "用户id:", v)
 			if in > -1 {
-				ok := MsgCountAdd(v, this.Appid, util.Int64All(group_id))
+				ok := MsgCountAdd(v, this.Appid, util.Int64All(group_id), this.MsgType)
 				if !ok {
 					log.Println("存redis:", ok, v)
 				}

+ 2 - 1
rpc/internal/config/config.go

@@ -23,7 +23,8 @@ type Config struct {
 		Pwd  string `json:"pwd"`
 		User string `json:"user"`
 	} `json:"mail"`
-	TidbEng string `json:"Tidb"`
+	TidbEng         string  `json:"Tidb"`
+	ClassSearchList []int64 `json:"ClassSearchList"` // 需要按照messageclass 查询的groupId
 }
 
 type mysqlConfig struct {

+ 3 - 0
rpc/message.go

@@ -67,6 +67,9 @@ func init() {
 	}
 	entity.Mysql.Init()
 	common.AllMsgType, entity.MessageColumn = common.MessageType()
+	// 初始化需要展示消息细化分类的groupid 和对应的class信息
+	common.InitClassSearchMap()
+
 	//初始化basemysql
 	entity.BaseMysql = &mysql.Mysql{
 		Address:      config.ConfigJson.BaseSource.Address,

+ 2 - 0
rpc/message.proto

@@ -199,6 +199,7 @@ message UserMsgListReq {
     int64 NewUserId   =12;//私信相关
     int64 PositionId  =13;//私信相关
     bool isContainLetter  =14;//是否包含私信未读数
+    bool isClassSearch  =15;// 是否是消息细化分类查询
 
 }
 
@@ -225,6 +226,7 @@ message AllSortData {
    string img = 3;
    int64 msgType = 4; //是否区分类型;
    repeated Messages data = 5; //
+    bool isClassSearch  =6;// 是否是消息细化分类查询
 }
 
 

+ 160 - 0
rpc/message/message.go

@@ -0,0 +1,160 @@
+// Code generated by goctl. DO NOT EDIT!
+// Source: message.proto
+
+package message
+
+import (
+	"context"
+
+	"app.yhyue.com/moapp/MessageCenter/rpc/type/message"
+
+	"github.com/zeromicro/go-zero/zrpc"
+	"google.golang.org/grpc"
+)
+
+type (
+	AllSortData            = message.AllSortData
+	BuoyMessages           = message.BuoyMessages
+	ChangeReadStatusReq    = message.ChangeReadStatusReq
+	ClearUnreadMsgReq      = message.ClearUnreadMsgReq
+	CustomWxTpl            = message.CustomWxTpl
+	FindUserBuoyMsgReq     = message.FindUserBuoyMsgReq
+	FindUserBuoyMsgRes     = message.FindUserBuoyMsgRes
+	FindUserMsgReq         = message.FindUserMsgReq
+	FindUserMsgRes         = message.FindUserMsgRes
+	GetClassUnreadCountReq = message.GetClassUnreadCountReq
+	GetLastMessageReq      = message.GetLastMessageReq
+	GetLastMessageRes      = message.GetLastMessageRes
+	GetMsgTypeReq          = message.GetMsgTypeReq
+	GetMsgTypeRes          = message.GetMsgTypeRes
+	GetUnreadClassCountReq = message.GetUnreadClassCountReq
+	GetUnreadClassCountRes = message.GetUnreadClassCountRes
+	MessageDetailReq       = message.MessageDetailReq
+	MessageDetailResp      = message.MessageDetailResp
+	Messages               = message.Messages
+	MsgOpenLogReq          = message.MsgOpenLogReq
+	MsgTypes               = message.MsgTypes
+	MultipleSaveMsgReq     = message.MultipleSaveMsgReq
+	MultipleSaveMsgResp    = message.MultipleSaveMsgResp
+	ResCount               = message.ResCount
+	Response               = message.Response
+	SendMsgResponse        = message.SendMsgResponse
+	TmplItem               = message.TmplItem
+	User                   = message.User
+	UserMsgList            = message.UserMsgList
+	UserMsgListReq         = message.UserMsgListReq
+	UserMsgListRes         = message.UserMsgListRes
+	UserUnreadMsgListReq   = message.UserUnreadMsgListReq
+	UserUnreadMsgListRes   = message.UserUnreadMsgListRes
+	WxTmplMsgRequest       = message.WxTmplMsgRequest
+	WxTmplResponse         = message.WxTmplResponse
+
+	Message interface {
+		// 批量保存消息
+		MultipleSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error)
+		//  修改消息阅读状态
+		ChangeReadStatus(ctx context.Context, in *ChangeReadStatusReq, opts ...grpc.CallOption) (*Response, error)
+		//   查询指定用户的历史消息记录
+		FindUserMsg(ctx context.Context, in *FindUserMsgReq, opts ...grpc.CallOption) (*FindUserMsgRes, error)
+		// 查看详细详情
+		FindMessageDetail(ctx context.Context, in *MessageDetailReq, opts ...grpc.CallOption) (*MessageDetailResp, error)
+		//   消息的分类
+		GetMsgType(ctx context.Context, in *GetMsgTypeReq, opts ...grpc.CallOption) (*GetMsgTypeRes, error)
+		//   查询指定用户的浮标消息
+		FindUserBuoyMsg(ctx context.Context, in *FindUserBuoyMsgReq, opts ...grpc.CallOption) (*FindUserBuoyMsgRes, error)
+		//    一键清空未读消息
+		ClearUnreadMsg(ctx context.Context, in *ClearUnreadMsgReq, opts ...grpc.CallOption) (*Response, error)
+		//    new用户消息列表
+		UserMsgList(ctx context.Context, in *UserMsgListReq, opts ...grpc.CallOption) (*UserMsgListRes, error)
+		//   发送剑鱼微信模版消息
+		SendWxTmplMsg(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error)
+		//    官网、移动端首页、工作桌面消息滚动
+		UserUnreadMsgList(ctx context.Context, in *UserUnreadMsgListReq, opts ...grpc.CallOption) (*UserUnreadMsgListRes, error)
+		//  点击消息-存查看记录
+		MsgOpenLog(ctx context.Context, in *MsgOpenLogReq, opts ...grpc.CallOption) (*Response, error)
+		//   发送剑鱼微信模版消息
+		AppLetterPush(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error)
+	}
+
+	defaultMessage struct {
+		cli zrpc.Client
+	}
+)
+
+func NewMessage(cli zrpc.Client) Message {
+	return &defaultMessage{
+		cli: cli,
+	}
+}
+
+// 批量保存消息
+func (m *defaultMessage) MultipleSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.MultipleSaveMsg(ctx, in, opts...)
+}
+
+//  修改消息阅读状态
+func (m *defaultMessage) ChangeReadStatus(ctx context.Context, in *ChangeReadStatusReq, opts ...grpc.CallOption) (*Response, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.ChangeReadStatus(ctx, in, opts...)
+}
+
+//   查询指定用户的历史消息记录
+func (m *defaultMessage) FindUserMsg(ctx context.Context, in *FindUserMsgReq, opts ...grpc.CallOption) (*FindUserMsgRes, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.FindUserMsg(ctx, in, opts...)
+}
+
+// 查看详细详情
+func (m *defaultMessage) FindMessageDetail(ctx context.Context, in *MessageDetailReq, opts ...grpc.CallOption) (*MessageDetailResp, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.FindMessageDetail(ctx, in, opts...)
+}
+
+//   消息的分类
+func (m *defaultMessage) GetMsgType(ctx context.Context, in *GetMsgTypeReq, opts ...grpc.CallOption) (*GetMsgTypeRes, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.GetMsgType(ctx, in, opts...)
+}
+
+//   查询指定用户的浮标消息
+func (m *defaultMessage) FindUserBuoyMsg(ctx context.Context, in *FindUserBuoyMsgReq, opts ...grpc.CallOption) (*FindUserBuoyMsgRes, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.FindUserBuoyMsg(ctx, in, opts...)
+}
+
+//    一键清空未读消息
+func (m *defaultMessage) ClearUnreadMsg(ctx context.Context, in *ClearUnreadMsgReq, opts ...grpc.CallOption) (*Response, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.ClearUnreadMsg(ctx, in, opts...)
+}
+
+//    new用户消息列表
+func (m *defaultMessage) UserMsgList(ctx context.Context, in *UserMsgListReq, opts ...grpc.CallOption) (*UserMsgListRes, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.UserMsgList(ctx, in, opts...)
+}
+
+//   发送剑鱼微信模版消息
+func (m *defaultMessage) SendWxTmplMsg(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.SendWxTmplMsg(ctx, in, opts...)
+}
+
+//    官网、移动端首页、工作桌面消息滚动
+func (m *defaultMessage) UserUnreadMsgList(ctx context.Context, in *UserUnreadMsgListReq, opts ...grpc.CallOption) (*UserUnreadMsgListRes, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.UserUnreadMsgList(ctx, in, opts...)
+}
+
+//  点击消息-存查看记录
+func (m *defaultMessage) MsgOpenLog(ctx context.Context, in *MsgOpenLogReq, opts ...grpc.CallOption) (*Response, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.MsgOpenLog(ctx, in, opts...)
+}
+
+//   发送剑鱼微信模版消息
+func (m *defaultMessage) AppLetterPush(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.AppLetterPush(ctx, in, opts...)
+}

+ 160 - 139
rpc/type/message/message.pb.go

@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.27.1
-// 	protoc        v3.20.0--rc2
+// 	protoc-gen-go v1.28.0
+// 	protoc        v3.19.4
 // source: message.proto
 
 package message
@@ -1935,6 +1935,7 @@ type UserMsgListReq struct {
 	NewUserId       int64  `protobuf:"varint,12,opt,name=NewUserId,proto3" json:"NewUserId,omitempty"`             //私信相关
 	PositionId      int64  `protobuf:"varint,13,opt,name=PositionId,proto3" json:"PositionId,omitempty"`           //私信相关
 	IsContainLetter bool   `protobuf:"varint,14,opt,name=isContainLetter,proto3" json:"isContainLetter,omitempty"` //是否包含私信未读数
+	IsClassSearch   bool   `protobuf:"varint,15,opt,name=isClassSearch,proto3" json:"isClassSearch,omitempty"`     // 是否是消息细化分类查询
 }
 
 func (x *UserMsgListReq) Reset() {
@@ -2060,6 +2061,13 @@ func (x *UserMsgListReq) GetIsContainLetter() bool {
 	return false
 }
 
+func (x *UserMsgListReq) GetIsClassSearch() bool {
+	if x != nil {
+		return x.IsClassSearch
+	}
+	return false
+}
+
 type UserMsgListRes struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -2234,8 +2242,9 @@ type AllSortData struct {
 	UnreadMessages int64       `protobuf:"varint,1,opt,name=unreadMessages,proto3" json:"unreadMessages,omitempty"`
 	Name           string      `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 	Img            string      `protobuf:"bytes,3,opt,name=img,proto3" json:"img,omitempty"`
-	MsgType        int64       `protobuf:"varint,4,opt,name=msgType,proto3" json:"msgType,omitempty"` //是否区分类型;
-	Data           []*Messages `protobuf:"bytes,5,rep,name=data,proto3" json:"data,omitempty"`        //
+	MsgType        int64       `protobuf:"varint,4,opt,name=msgType,proto3" json:"msgType,omitempty"`             //是否区分类型;
+	Data           []*Messages `protobuf:"bytes,5,rep,name=data,proto3" json:"data,omitempty"`                    //
+	IsClassSearch  bool        `protobuf:"varint,6,opt,name=isClassSearch,proto3" json:"isClassSearch,omitempty"` // 是否是消息细化分类查询
 }
 
 func (x *AllSortData) Reset() {
@@ -2305,6 +2314,13 @@ func (x *AllSortData) GetData() []*Messages {
 	return nil
 }
 
+func (x *AllSortData) GetIsClassSearch() bool {
+	if x != nil {
+		return x.IsClassSearch
+	}
+	return false
+}
+
 type WxTmplResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -2976,7 +2992,7 @@ var file_message_proto_rawDesc = []byte{
 	0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x04,
 	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x4e,
 	0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
-	0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x86, 0x03, 0x0a, 0x0e, 0x55, 0x73,
+	0x4e, 0x65, 0x77, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0xac, 0x03, 0x0a, 0x0e, 0x55, 0x73,
 	0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06,
 	0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73,
 	0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20,
@@ -3001,142 +3017,147 @@ var file_message_proto_rawDesc = []byte{
 	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x69, 0x73, 0x43, 0x6f,
 	0x6e, 0x74, 0x61, 0x69, 0x6e, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28,
 	0x08, 0x52, 0x0f, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x4c, 0x65, 0x74, 0x74,
-	0x65, 0x72, 0x22, 0xe8, 0x01, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69,
-	0x73, 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
-	0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x73, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x61,
-	0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x04, 0x6c, 0x61, 0x73,
-	0x74, 0x12, 0x2c, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x05, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x53,
-	0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12,
-	0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
-	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18,
-	0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x22, 0x94, 0x01,
-	0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x25, 0x0a,
-	0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x04,
-	0x64, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x08, 0x73, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61,
-	0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x2e, 0x41, 0x6c, 0x6c, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x73, 0x6f,
-	0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06,
-	0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x6e,
-	0x72, 0x65, 0x61, 0x64, 0x22, 0x9c, 0x01, 0x0a, 0x0b, 0x41, 0x6c, 0x6c, 0x53, 0x6f, 0x72, 0x74,
-	0x44, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x75, 0x6e,
-	0x72, 0x65, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x12, 0x10, 0x0a, 0x03, 0x69, 0x6d, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x69,
-	0x6d, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20,
-	0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x04,
-	0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73,
-	0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x04, 0x64,
-	0x61, 0x74, 0x61, 0x22, 0x48, 0x0a, 0x0e, 0x57, 0x78, 0x54, 0x6d, 0x70, 0x6c, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x74,
-	0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x54, 0x6f,
-	0x74, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x98, 0x01,
-	0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x73, 0x67, 0x4c,
-	0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14,
-	0x0a, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61,
-	0x70, 0x70, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x53, 0x65, 0x74, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x53, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08,
-	0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08,
-	0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x4e, 0x65,
-	0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x69, 0x73,
-	0x4e, 0x65, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x22, 0x81, 0x01, 0x0a, 0x14, 0x55, 0x73, 0x65,
-	0x72, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
-	0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
-	0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
-	0x25, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e,
-	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
-	0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
-	0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd0, 0x01, 0x0a,
-	0x10, 0x57, 0x78, 0x54, 0x6d, 0x70, 0x6c, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x70,
-	0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x18, 0x0a,
-	0x07, 0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07,
-	0x6d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a,
-	0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64,
-	0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x77,
-	0x34, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x34, 0x12, 0x10, 0x0a,
-	0x03, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22,
-	0x41, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x22, 0x75, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x4f, 0x70, 0x65, 0x6e, 0x4c, 0x6f, 0x67,
-	0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x73, 0x67, 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x73, 0x67, 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x12,
-	0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x03, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x75,
-	0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65,
-	0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x32, 0xce, 0x06, 0x0a, 0x07, 0x4d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4c, 0x0a, 0x0f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c,
-	0x65, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x1b, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x4d,
-	0x73, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
-	0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x73, 0x67, 0x52,
-	0x65, 0x73, 0x70, 0x12, 0x43, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x61,
-	0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64,
-	0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71,
-	0x1a, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55,
-	0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x11, 0x46, 0x69, 0x6e,
-	0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x19,
+	0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x53, 0x65, 0x61,
+	0x72, 0x63, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x73, 0x43, 0x6c, 0x61,
+	0x73, 0x73, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0xe8, 0x01, 0x0a, 0x0e, 0x55, 0x73, 0x65,
+	0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63,
+	0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12,
+	0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x69, 0x73,
+	0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74,
+	0x12, 0x25, 0x0a, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
 	0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3c, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x73, 0x67, 0x54,
-	0x79, 0x70, 0x65, 0x12, 0x16, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65,
-	0x74, 0x4d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x6d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65,
-	0x52, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x42,
-	0x75, 0x6f, 0x79, 0x4d, 0x73, 0x67, 0x12, 0x1b, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x42, 0x75, 0x6f, 0x79, 0x4d, 0x73, 0x67,
-	0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69,
-	0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x42, 0x75, 0x6f, 0x79, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x73,
-	0x12, 0x3f, 0x0a, 0x0e, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d,
-	0x73, 0x67, 0x12, 0x1a, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6c, 0x65,
-	0x61, 0x72, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x11,
-	0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x3f, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74,
-	0x12, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d,
-	0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52,
-	0x65, 0x73, 0x12, 0x44, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x78, 0x54, 0x6d, 0x70, 0x6c,
-	0x4d, 0x73, 0x67, 0x12, 0x19, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x57, 0x78,
-	0x54, 0x6d, 0x70, 0x6c, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
-	0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x73, 0x67,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x11, 0x55, 0x73, 0x65, 0x72,
-	0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x2e,
-	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x6e, 0x72, 0x65,
-	0x61, 0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6d,
-	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x6e, 0x72, 0x65, 0x61,
-	0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x4d,
-	0x73, 0x67, 0x4f, 0x70, 0x65, 0x6e, 0x4c, 0x6f, 0x67, 0x12, 0x16, 0x2e, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x2e, 0x4d, 0x73, 0x67, 0x4f, 0x70, 0x65, 0x6e, 0x4c, 0x6f, 0x67, 0x52, 0x65,
+	0x73, 0x52, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d,
+	0x6e, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x63,
+	0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75,
+	0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x75, 0x6e, 0x72,
+	0x65, 0x61, 0x64, 0x22, 0x94, 0x01, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c,
+	0x69, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x08, 0x73, 0x6f,
+	0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x61,
+	0x74, 0x61, 0x52, 0x08, 0x73, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75,
+	0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x22, 0xc2, 0x01, 0x0a, 0x0b, 0x41,
+	0x6c, 0x6c, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0e, 0x75, 0x6e,
+	0x72, 0x65, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x0e, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x6d, 0x67, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x69, 0x6d, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x54,
+	0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x54, 0x79,
+	0x70, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x73, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x73, 0x43,
+	0x6c, 0x61, 0x73, 0x73, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08,
+	0x52, 0x0d, 0x69, 0x73, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22,
+	0x48, 0x0a, 0x0e, 0x57, 0x78, 0x54, 0x6d, 0x70, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x12,
+	0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x14, 0x55, 0x73,
+	0x65, 0x72, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52,
+	0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x70,
+	0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x69, 0x64,
+	0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x53, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x06, 0x6f, 0x66, 0x66, 0x53, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65,
+	0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65,
+	0x53, 0x69, 0x7a, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x73, 0x4e, 0x65, 0x65, 0x64, 0x44, 0x61,
+	0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x69, 0x73, 0x4e, 0x65, 0x65, 0x64,
+	0x44, 0x61, 0x74, 0x61, 0x22, 0x81, 0x01, 0x0a, 0x14, 0x55, 0x73, 0x65, 0x72, 0x55, 0x6e, 0x72,
+	0x65, 0x61, 0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a,
+	0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64,
+	0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x6c,
+	0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x04, 0x6c, 0x69,
+	0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd0, 0x01, 0x0a, 0x10, 0x57, 0x78, 0x54,
+	0x6d, 0x70, 0x6c, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a,
+	0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x6f, 0x73, 0x69, 0x74,
+	0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x6f,
+	0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x73, 0x67,
+	0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x73, 0x67, 0x54,
+	0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74,
+	0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x34, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x34, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c,
+	0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x41, 0x0a, 0x0f, 0x53,
+	0x65, 0x6e, 0x64, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14,
+	0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74,
+	0x6f, 0x74, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x75,
+	0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x4f, 0x70, 0x65, 0x6e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x12,
+	0x1a, 0x0a, 0x08, 0x6d, 0x73, 0x67, 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x08, 0x6d, 0x73, 0x67, 0x4c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70,
+	0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70,
+	0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49,
+	0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12,
+	0x14, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
+	0x61, 0x70, 0x70, 0x49, 0x64, 0x32, 0xce, 0x06, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x12, 0x4c, 0x0a, 0x0f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x53, 0x61, 0x76,
+	0x65, 0x4d, 0x73, 0x67, 0x12, 0x1b, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x6d,
+	0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x73, 0x67, 0x52, 0x65,
+	0x71, 0x1a, 0x1c, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x6d, 0x75, 0x6c, 0x74,
+	0x69, 0x70, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x73, 0x70, 0x12,
+	0x43, 0x0a, 0x10, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x53, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x68,
+	0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
 	0x71, 0x1a, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x4c, 0x65, 0x74, 0x74, 0x65,
-	0x72, 0x50, 0x75, 0x73, 0x68, 0x12, 0x19, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
-	0x57, 0x78, 0x54, 0x6d, 0x70, 0x6c, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x18, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d,
-	0x73, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0a, 0x5a, 0x08, 0x6d, 0x65,
-	0x73, 0x73, 0x61, 0x67, 0x65, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72,
+	0x4d, 0x73, 0x67, 0x12, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69,
+	0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d,
+	0x73, 0x67, 0x52, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x19, 0x2e, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
+	0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73,
+	0x70, 0x12, 0x3c, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12,
+	0x16, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x73, 0x67,
+	0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x73, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x12,
+	0x4b, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73, 0x65, 0x72, 0x42, 0x75, 0x6f, 0x79, 0x4d,
+	0x73, 0x67, 0x12, 0x1b, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6e,
+	0x64, 0x55, 0x73, 0x65, 0x72, 0x42, 0x75, 0x6f, 0x79, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x1a,
+	0x1b, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x55, 0x73,
+	0x65, 0x72, 0x42, 0x75, 0x6f, 0x79, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x0e,
+	0x43, 0x6c, 0x65, 0x61, 0x72, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x73, 0x67, 0x12, 0x1a,
+	0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x55, 0x6e,
+	0x72, 0x65, 0x61, 0x64, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a,
+	0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69,
+	0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
+	0x55, 0x73, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x12, 0x44,
+	0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x78, 0x54, 0x6d, 0x70, 0x6c, 0x4d, 0x73, 0x67, 0x12,
+	0x19, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x57, 0x78, 0x54, 0x6d, 0x70, 0x6c,
+	0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x11, 0x55, 0x73, 0x65, 0x72, 0x55, 0x6e, 0x72, 0x65,
+	0x61, 0x64, 0x4d, 0x73, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x73,
+	0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x4d, 0x73, 0x67,
+	0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x4d, 0x73, 0x67, 0x4f, 0x70,
+	0x65, 0x6e, 0x4c, 0x6f, 0x67, 0x12, 0x16, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
+	0x4d, 0x73, 0x67, 0x4f, 0x70, 0x65, 0x6e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e,
+	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x44, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x4c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x50, 0x75, 0x73,
+	0x68, 0x12, 0x19, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x57, 0x78, 0x54, 0x6d,
+	0x70, 0x6c, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x73, 0x67, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0a, 0x5a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (

+ 1 - 1
rpc/type/message/message_grpc.pb.go

@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
 // - protoc-gen-go-grpc v1.2.0
-// - protoc             v3.20.0--rc2
+// - protoc             v3.19.4
 // source: message.proto
 
 package message

+ 15 - 0
test.http

@@ -0,0 +1,15 @@
+POST https://webdev-webtest.jydev.jianyu360.com/jyapi/messageCenter/MessageList
+Content-Type: application/json
+Cookie: SESSIONID=48a82dd61f617fcc9c35addf63b825d5c832e2fb;
+
+{
+  "offset": 1,
+  "isColumn": true,
+  "isColumnNewMsg": true,
+  "isMsgList": false,
+  "sortSize": 1,
+  "isClassSearch": true,
+  "msgType": 11
+}
+
+###