mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-12-03 02:42:19 +08:00
feat: add GetConversationList Api
This commit is contained in:
parent
755eeef1e1
commit
c682bb8d1e
2
go.mod
2
go.mod
@ -176,4 +176,4 @@ require (
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/OpenIMSDK/protocol v0.0.31 => github.com/luhaoling/protocol v0.0.0-20231201032120-22bebe035ae3
|
||||
replace github.com/OpenIMSDK/protocol v0.0.31 => github.com/luhaoling/protocol v0.0.0-20231208093819-b7b045d52e56
|
||||
|
||||
4
go.sum
4
go.sum
@ -274,8 +274,8 @@ github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205Ah
|
||||
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
|
||||
github.com/lithammer/shortuuid v3.0.0+incompatible h1:NcD0xWW/MZYXEHa6ITy6kaXN5nwm/V115vj2YXfhS0w=
|
||||
github.com/lithammer/shortuuid v3.0.0+incompatible/go.mod h1:FR74pbAuElzOUuenUHTK2Tciko1/vKuIKS9dSkDrA4w=
|
||||
github.com/luhaoling/protocol v0.0.0-20231201032120-22bebe035ae3 h1:tWCCSHzacKfJ1v63rNu65fVLytsFV7rCdI+EjwwZmx8=
|
||||
github.com/luhaoling/protocol v0.0.0-20231201032120-22bebe035ae3/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/luhaoling/protocol v0.0.0-20231208093819-b7b045d52e56 h1:Fwvjj84aTcb+1ELt8HNSqVgWJYCJ6+1ui7yH0dTkVoQ=
|
||||
github.com/luhaoling/protocol v0.0.0-20231208093819-b7b045d52e56/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
|
||||
@ -125,8 +125,8 @@ func (m *MessageApi) GetConversationsHasReadAndMaxSeq(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.GetConversationsHasReadAndMaxSeq, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) GetConversationsUnreadSeqAndMaxSeq(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.GetConversationsUnreadSeqAndMaxSeq, m.Client, c)
|
||||
func (m *MessageApi) GetConversationsList(c *gin.Context) {
|
||||
a2r.Call(msg.MsgClient.GetConversationList, m.Client, c)
|
||||
}
|
||||
|
||||
func (m *MessageApi) SetConversationHasReadSeq(c *gin.Context) {
|
||||
|
||||
@ -175,7 +175,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
||||
msgGroup.POST("/mark_msgs_as_read", m.MarkMsgsAsRead)
|
||||
msgGroup.POST("/mark_conversation_as_read", m.MarkConversationAsRead)
|
||||
msgGroup.POST("/get_conversations_has_read_and_max_seq", m.GetConversationsHasReadAndMaxSeq)
|
||||
msgGroup.POST("/get_conversations_unread_seq_and_max_seq", m.GetConversationsUnreadSeqAndMaxSeq)
|
||||
msgGroup.POST("/get_conversations_list", m.GetConversationsList)
|
||||
msgGroup.POST("/set_conversation_has_read_seq", m.SetConversationHasReadSeq)
|
||||
|
||||
msgGroup.POST("/clear_conversation_msg", m.ClearConversationsMsg)
|
||||
|
||||
@ -16,7 +16,6 @@ package friend
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
@ -446,3 +445,7 @@ func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, req *pbfrien
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *friendServer) PinFriends(ctx context.Context, req *pbfriend.PinFriendsReq) (*pbfriend.PinFriendsResp, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ package msg
|
||||
import (
|
||||
"context"
|
||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
"sort"
|
||||
|
||||
utils2 "github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
@ -71,7 +72,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *m
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (m *msgServer) GetConversationsUnreadSeqAndMaxSeq(ctx context.Context, req *msg.GetConversationsUnreadSeqAndMaxSeqReq) (resp *msg.GetConversationsUnreadSeqAndMaxSeqResp, err error) {
|
||||
func (m *msgServer) GetConversationList(ctx context.Context, req *msg.GetConversationListReq) (resp *msg.GetConversationListResp, err error) {
|
||||
var conversationIDs []string
|
||||
if len(req.ConversationIDs) == 0 {
|
||||
conversationIDs, err = m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
||||
@ -81,38 +82,56 @@ func (m *msgServer) GetConversationsUnreadSeqAndMaxSeq(ctx context.Context, req
|
||||
} else {
|
||||
conversationIDs = req.ConversationIDs
|
||||
}
|
||||
hasReadSeqs, err := m.MsgDatabase.GetHasReadSeqs(ctx, req.UserID, conversationIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conversations, err := m.Conversation.GetConversations(ctx, req.UserID, conversationIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conversationMaxSeqMap := make(map[string]int64)
|
||||
for _, conversation := range conversations {
|
||||
if conversation.MaxSeq != 0 {
|
||||
conversationMaxSeqMap[conversation.ConversationID] = conversation.MaxSeq
|
||||
}
|
||||
}
|
||||
|
||||
maxSeqs, err := m.MsgDatabase.GetMaxSeqs(ctx, conversationIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp = &msg.GetConversationsUnreadSeqAndMaxSeqResp{Seqs: make(map[string]*msg.UnreadSeqs)}
|
||||
for conversarionID, maxSeq := range maxSeqs {
|
||||
resp.Seqs[conversarionID] = &msg.UnreadSeqs{
|
||||
<<<<<<< HEAD
|
||||
UnreadSeq: maxSeq - hasReadSeqs[conversarionID],
|
||||
=======
|
||||
UnreadSeq: hasReadSeqs[conversarionID],
|
||||
>>>>>>> c13411da69a6457ba810c071a5d7f462eaa1531e
|
||||
MaxSeq: maxSeq,
|
||||
}
|
||||
if v, ok := conversationMaxSeqMap[conversarionID]; ok {
|
||||
resp.Seqs[conversarionID].MaxSeq = v
|
||||
}
|
||||
|
||||
chatLogs, err := m.MsgDatabase.FindOneByDocIDs(ctx, conversationIDs, maxSeqs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conversationMsg, err := m.getConversationInfo(ctx, chatLogs, req.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hasReadSeqs, err := m.MsgDatabase.GetHasReadSeqs(ctx, req.UserID, conversationIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conversation_unreadCount := make(map[string]int64)
|
||||
for conversationID, maxSeq := range maxSeqs {
|
||||
conversation_unreadCount[conversationID] = maxSeq - hasReadSeqs[conversationID]
|
||||
}
|
||||
|
||||
conversation_isPinkTime := make(map[int64]string)
|
||||
conversation_notPinkTime := make(map[int64]string)
|
||||
for _, v := range conversations {
|
||||
conversationID := v.ConversationID
|
||||
time := conversationMsg[conversationID].MsgInfo.LatestMsgRecvTime
|
||||
conversationMsg[conversationID].RecvMsgOpt = v.RecvMsgOpt
|
||||
if v.IsPinned {
|
||||
conversationMsg[conversationID].IsPinned = v.IsPinned
|
||||
conversation_isPinkTime[time] = conversationID
|
||||
continue
|
||||
}
|
||||
conversation_notPinkTime[time] = conversationID
|
||||
}
|
||||
resp = &msg.GetConversationListResp{
|
||||
ConversationElems: []*msg.ConversationElem{},
|
||||
}
|
||||
|
||||
m.conversationSort(conversation_isPinkTime, resp, conversation_unreadCount, conversationMsg)
|
||||
m.conversationSort(conversation_notPinkTime, resp, conversation_unreadCount, conversationMsg)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@ -254,3 +273,100 @@ func (m *msgServer) sendMarkAsReadNotification(
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *msgServer) conversationSort(
|
||||
conversations map[int64]string,
|
||||
resp *msg.GetConversationListResp,
|
||||
conversation_unreadCount map[string]int64,
|
||||
conversationMsg map[string]*msg.ConversationElem,
|
||||
) {
|
||||
keys := []int64{}
|
||||
for key := range conversations {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Slice(keys[:], func(i, j int) bool {
|
||||
return keys[i] > keys[j]
|
||||
})
|
||||
index := 0
|
||||
|
||||
cons := make([]*msg.ConversationElem, len(conversations))
|
||||
for _, v := range keys {
|
||||
conversationID := conversations[v]
|
||||
conversationElem := conversationMsg[conversationID]
|
||||
conversationElem.UnreadCount = conversation_unreadCount[conversationID]
|
||||
cons[index] = conversationElem
|
||||
index++
|
||||
}
|
||||
resp.ConversationElems = append(resp.ConversationElems, cons...)
|
||||
}
|
||||
|
||||
func (m *msgServer) getConversationInfo(
|
||||
ctx context.Context,
|
||||
chatLogs map[string]*sdkws.MsgData,
|
||||
userID string) (map[string]*msg.ConversationElem, error) {
|
||||
var (
|
||||
sendIDs []string
|
||||
groupIDs []string
|
||||
sendMap = make(map[string]*sdkws.UserInfo)
|
||||
groupMap = make(map[string]*sdkws.GroupInfo)
|
||||
conversationMsg = make(map[string]*msg.ConversationElem)
|
||||
)
|
||||
for _, chatLog := range chatLogs {
|
||||
switch chatLog.SessionType {
|
||||
case constant.SingleChatType:
|
||||
if chatLog.SendID == userID {
|
||||
sendIDs = append(sendIDs, chatLog.RecvID)
|
||||
}
|
||||
sendIDs = append(sendIDs, chatLog.SendID)
|
||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||
groupIDs = append(groupIDs, chatLog.GroupID)
|
||||
sendIDs = append(sendIDs, chatLog.SendID)
|
||||
}
|
||||
}
|
||||
if len(sendIDs) != 0 {
|
||||
sendInfos, err := m.User.GetUsersInfo(ctx, sendIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, sendInfo := range sendInfos {
|
||||
sendMap[sendInfo.UserID] = sendInfo
|
||||
}
|
||||
}
|
||||
if len(groupIDs) != 0 {
|
||||
groupInfos, err := m.Group.GetGroupInfos(ctx, groupIDs, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, groupInfo := range groupInfos {
|
||||
groupMap[groupInfo.GroupID] = groupInfo
|
||||
}
|
||||
}
|
||||
for conversationID, chatLog := range chatLogs {
|
||||
pbchatLog := &msg.ConversationElem{}
|
||||
msgInfo := &msg.MsgInfo{}
|
||||
utils2.CopyStructFields(msgInfo, chatLog)
|
||||
switch chatLog.SessionType {
|
||||
case constant.SingleChatType:
|
||||
if chatLog.SendID == userID {
|
||||
msgInfo.FaceURL = sendMap[chatLog.RecvID].FaceURL
|
||||
msgInfo.SenderName = sendMap[chatLog.RecvID].Nickname
|
||||
break
|
||||
}
|
||||
msgInfo.FaceURL = sendMap[chatLog.SendID].FaceURL
|
||||
msgInfo.SenderName = sendMap[chatLog.SendID].Nickname
|
||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||
msgInfo.GroupName = groupMap[chatLog.GroupID].GroupName
|
||||
msgInfo.GroupFaceURL = groupMap[chatLog.GroupID].FaceURL
|
||||
msgInfo.GroupMemberCount = groupMap[chatLog.GroupID].MemberCount
|
||||
msgInfo.GroupID = chatLog.GroupID
|
||||
msgInfo.GroupType = groupMap[chatLog.GroupID].GroupType
|
||||
msgInfo.SenderName = sendMap[chatLog.SendID].Nickname
|
||||
}
|
||||
pbchatLog.ConversationID = conversationID
|
||||
msgInfo.LatestMsgRecvTime = chatLog.SendTime
|
||||
pbchatLog.MsgInfo = msgInfo
|
||||
conversationMsg[conversationID] = pbchatLog
|
||||
}
|
||||
return conversationMsg, nil
|
||||
}
|
||||
|
||||
@ -64,6 +64,30 @@ type SendMsgReq struct {
|
||||
SendMsg
|
||||
}
|
||||
|
||||
type GetConversationListReq struct {
|
||||
// userID uniquely identifies the user.
|
||||
UserID string `protobuf:"bytes,1,opt,name=userID,proto3" json:"userID,omitempty" binding:"required"`
|
||||
|
||||
// ConversationIDs contains a list of unique identifiers for conversations.
|
||||
ConversationIDs []string `protobuf:"bytes,2,rep,name=conversationIDs,proto3" json:"conversationIDs,omitempty"`
|
||||
}
|
||||
|
||||
type GetConversationListResp struct {
|
||||
// ConversationElems is a map that associates conversation IDs with their respective details.
|
||||
ConversationElems map[string]*ConversationElem `protobuf:"bytes,1,rep,name=conversationElems,proto3" json:"conversationElems,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
}
|
||||
|
||||
type ConversationElem struct {
|
||||
// MaxSeq represents the maximum sequence number within the conversation.
|
||||
MaxSeq int64 `protobuf:"varint,1,opt,name=maxSeq,proto3" json:"maxSeq,omitempty"`
|
||||
|
||||
// UnreadSeq represents the number of unread messages in the conversation.
|
||||
UnreadSeq int64 `protobuf:"varint,2,opt,name=unreadSeq,proto3" json:"unreadSeq,omitempty"`
|
||||
|
||||
// LastSeqTime represents the timestamp of the last sequence in the conversation.
|
||||
LastSeqTime int64 `protobuf:"varint,3,opt,name=LastSeqTime,proto3" json:"LastSeqTime,omitempty"`
|
||||
}
|
||||
|
||||
// BatchSendMsgReq defines the structure for sending a message to multiple recipients.
|
||||
type BatchSendMsgReq struct {
|
||||
SendMsg
|
||||
|
||||
@ -18,6 +18,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
@ -98,6 +99,7 @@ type CommonMsgDatabase interface {
|
||||
SetSendMsgStatus(ctx context.Context, id string, status int32) error
|
||||
GetSendMsgStatus(ctx context.Context, id string) (int32, error)
|
||||
SearchMessage(ctx context.Context, req *pbmsg.SearchMessageReq) (total int32, msgData []*sdkws.MsgData, err error)
|
||||
FindOneByDocIDs(ctx context.Context, docIDs []string, seqs map[string]int64) (map[string]*sdkws.MsgData, error)
|
||||
|
||||
// to mq
|
||||
MsgToMQ(ctx context.Context, key string, msg2mq *sdkws.MsgData) error
|
||||
@ -1047,6 +1049,23 @@ func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbmsg.Searc
|
||||
return total, totalMsgs, nil
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) FindOneByDocIDs(ctx context.Context, conversationIDs []string, seqs map[string]int64) (map[string]*sdkws.MsgData, error) {
|
||||
totalMsgs := make(map[string]*sdkws.MsgData)
|
||||
for _, conversationID := range conversationIDs {
|
||||
len := seqs[conversationID]
|
||||
seq := len / 100
|
||||
index := (len % 100) - 1
|
||||
|
||||
docID := conversationID + ":" + fmt.Sprintf("%d", seq)
|
||||
msgs, err := db.msgDocDatabase.FindOneByDocID(ctx, docID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
totalMsgs[conversationID] = convert.MsgDB2Pb(msgs.Msg[index].Msg)
|
||||
}
|
||||
return totalMsgs, nil
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) {
|
||||
db.msgDocDatabase.ConvertMsgsDocLen(ctx, conversationIDs)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user