mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-04-05 20:11:14 +08:00
* pb * fix: Modifying other fields while setting IsPrivateChat does not take effect * fix: quote message error revoke * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * refactoring scheduled tasks * upgrading pkg tools * fix
250 lines
7.3 KiB
Go
250 lines
7.3 KiB
Go
package jssdk
|
|
|
|
import (
|
|
"context"
|
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
|
"sort"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/openimsdk/protocol/conversation"
|
|
"github.com/openimsdk/protocol/jssdk"
|
|
"github.com/openimsdk/protocol/msg"
|
|
"github.com/openimsdk/protocol/relation"
|
|
"github.com/openimsdk/protocol/sdkws"
|
|
"github.com/openimsdk/tools/mcontext"
|
|
"github.com/openimsdk/tools/utils/datautil"
|
|
)
|
|
|
|
const (
|
|
maxGetActiveConversation = 500
|
|
defaultGetActiveConversation = 100
|
|
)
|
|
|
|
func NewJSSdkApi(userClient *rpcli.UserClient, relationClient *rpcli.RelationClient, groupClient *rpcli.GroupClient,
|
|
conversationClient *rpcli.ConversationClient, msgClient *rpcli.MsgClient) *JSSdk {
|
|
return &JSSdk{
|
|
userClient: userClient,
|
|
relationClient: relationClient,
|
|
groupClient: groupClient,
|
|
conversationClient: conversationClient,
|
|
msgClient: msgClient,
|
|
}
|
|
}
|
|
|
|
type JSSdk struct {
|
|
userClient *rpcli.UserClient
|
|
relationClient *rpcli.RelationClient
|
|
groupClient *rpcli.GroupClient
|
|
conversationClient *rpcli.ConversationClient
|
|
msgClient *rpcli.MsgClient
|
|
}
|
|
|
|
func (x *JSSdk) GetActiveConversations(c *gin.Context) {
|
|
call(c, x.getActiveConversations)
|
|
}
|
|
|
|
func (x *JSSdk) GetConversations(c *gin.Context) {
|
|
call(c, x.getConversations)
|
|
}
|
|
|
|
func (x *JSSdk) fillConversations(ctx context.Context, conversations []*jssdk.ConversationMsg) error {
|
|
if len(conversations) == 0 {
|
|
return nil
|
|
}
|
|
var (
|
|
userIDs []string
|
|
groupIDs []string
|
|
)
|
|
for _, c := range conversations {
|
|
if c.Conversation.GroupID == "" {
|
|
userIDs = append(userIDs, c.Conversation.UserID)
|
|
} else {
|
|
groupIDs = append(groupIDs, c.Conversation.GroupID)
|
|
}
|
|
}
|
|
var (
|
|
userMap map[string]*sdkws.UserInfo
|
|
friendMap map[string]*relation.FriendInfoOnly
|
|
groupMap map[string]*sdkws.GroupInfo
|
|
)
|
|
if len(userIDs) > 0 {
|
|
users, err := x.userClient.GetUsersInfo(ctx, userIDs)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
friends, err := x.relationClient.GetFriendsInfo(ctx, conversations[0].Conversation.OwnerUserID, userIDs)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
userMap = datautil.SliceToMap(users, (*sdkws.UserInfo).GetUserID)
|
|
friendMap = datautil.SliceToMap(friends, (*relation.FriendInfoOnly).GetFriendUserID)
|
|
}
|
|
if len(groupIDs) > 0 {
|
|
groups, err := x.groupClient.GetGroupsInfo(ctx, groupIDs)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
groupMap = datautil.SliceToMap(groups, (*sdkws.GroupInfo).GetGroupID)
|
|
}
|
|
for _, c := range conversations {
|
|
if c.Conversation.GroupID == "" {
|
|
c.User = userMap[c.Conversation.UserID]
|
|
c.Friend = friendMap[c.Conversation.UserID]
|
|
} else {
|
|
c.Group = groupMap[c.Conversation.GroupID]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (x *JSSdk) getActiveConversations(ctx context.Context, req *jssdk.GetActiveConversationsReq) (*jssdk.GetActiveConversationsResp, error) {
|
|
if req.Count <= 0 || req.Count > maxGetActiveConversation {
|
|
req.Count = defaultGetActiveConversation
|
|
}
|
|
req.OwnerUserID = mcontext.GetOpUserID(ctx)
|
|
conversationIDs, err := x.conversationClient.GetConversationIDs(ctx, req.OwnerUserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(conversationIDs) == 0 {
|
|
return &jssdk.GetActiveConversationsResp{}, nil
|
|
}
|
|
readSeq, err := x.msgClient.GetHasReadSeqs(ctx, conversationIDs, req.OwnerUserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
activeConversation, err := x.msgClient.GetActiveConversation(ctx, conversationIDs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(activeConversation) == 0 {
|
|
return &jssdk.GetActiveConversationsResp{}, nil
|
|
}
|
|
sortConversations := sortActiveConversations{
|
|
Conversation: activeConversation,
|
|
}
|
|
if len(activeConversation) > 1 {
|
|
pinnedConversationIDs, err := x.conversationClient.GetPinnedConversationIDs(ctx, req.OwnerUserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
sortConversations.PinnedConversationIDs = datautil.SliceSet(pinnedConversationIDs)
|
|
}
|
|
sort.Sort(&sortConversations)
|
|
sortList := sortConversations.Top(int(req.Count))
|
|
conversations, err := x.conversationClient.GetConversations(ctx, datautil.Slice(sortList, func(c *msg.ActiveConversation) string {
|
|
return c.ConversationID
|
|
}), req.OwnerUserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
msgs, err := x.msgClient.GetSeqMessage(ctx, req.OwnerUserID, datautil.Slice(sortList, func(c *msg.ActiveConversation) *msg.ConversationSeqs {
|
|
return &msg.ConversationSeqs{
|
|
ConversationID: c.ConversationID,
|
|
Seqs: []int64{c.MaxSeq},
|
|
}
|
|
}))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
conversationMap := datautil.SliceToMap(conversations, func(c *conversation.Conversation) string {
|
|
return c.ConversationID
|
|
})
|
|
resp := make([]*jssdk.ConversationMsg, 0, len(sortList))
|
|
for _, c := range sortList {
|
|
conv, ok := conversationMap[c.ConversationID]
|
|
if !ok {
|
|
continue
|
|
}
|
|
var lastMsg *sdkws.MsgData
|
|
if msgList, ok := msgs[c.ConversationID]; ok && len(msgList.Msgs) > 0 {
|
|
lastMsg = msgList.Msgs[0]
|
|
}
|
|
resp = append(resp, &jssdk.ConversationMsg{
|
|
Conversation: conv,
|
|
LastMsg: lastMsg,
|
|
MaxSeq: c.MaxSeq,
|
|
ReadSeq: readSeq[c.ConversationID],
|
|
})
|
|
}
|
|
if err := x.fillConversations(ctx, resp); err != nil {
|
|
return nil, err
|
|
}
|
|
var unreadCount int64
|
|
for _, c := range activeConversation {
|
|
count := c.MaxSeq - readSeq[c.ConversationID]
|
|
if count > 0 {
|
|
unreadCount += count
|
|
}
|
|
}
|
|
return &jssdk.GetActiveConversationsResp{
|
|
Conversations: resp,
|
|
UnreadCount: unreadCount,
|
|
}, nil
|
|
}
|
|
|
|
func (x *JSSdk) getConversations(ctx context.Context, req *jssdk.GetConversationsReq) (*jssdk.GetConversationsResp, error) {
|
|
req.OwnerUserID = mcontext.GetOpUserID(ctx)
|
|
conversations, err := x.conversationClient.GetConversations(ctx, req.ConversationIDs, req.OwnerUserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(conversations) == 0 {
|
|
return &jssdk.GetConversationsResp{}, nil
|
|
}
|
|
req.ConversationIDs = datautil.Slice(conversations, func(c *conversation.Conversation) string {
|
|
return c.ConversationID
|
|
})
|
|
maxSeqs, err := x.msgClient.GetMaxSeqs(ctx, req.ConversationIDs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
readSeqs, err := x.msgClient.GetHasReadSeqs(ctx, req.ConversationIDs, req.OwnerUserID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
conversationSeqs := make([]*msg.ConversationSeqs, 0, len(conversations))
|
|
for _, c := range conversations {
|
|
if seq := maxSeqs[c.ConversationID]; seq > 0 {
|
|
conversationSeqs = append(conversationSeqs, &msg.ConversationSeqs{
|
|
ConversationID: c.ConversationID,
|
|
Seqs: []int64{seq},
|
|
})
|
|
}
|
|
}
|
|
var msgs map[string]*sdkws.PullMsgs
|
|
if len(conversationSeqs) > 0 {
|
|
msgs, err = x.msgClient.GetSeqMessage(ctx, req.OwnerUserID, conversationSeqs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
resp := make([]*jssdk.ConversationMsg, 0, len(conversations))
|
|
for _, c := range conversations {
|
|
var lastMsg *sdkws.MsgData
|
|
if msgList, ok := msgs[c.ConversationID]; ok && len(msgList.Msgs) > 0 {
|
|
lastMsg = msgList.Msgs[0]
|
|
}
|
|
resp = append(resp, &jssdk.ConversationMsg{
|
|
Conversation: c,
|
|
LastMsg: lastMsg,
|
|
MaxSeq: maxSeqs[c.ConversationID],
|
|
ReadSeq: readSeqs[c.ConversationID],
|
|
})
|
|
}
|
|
if err := x.fillConversations(ctx, resp); err != nil {
|
|
return nil, err
|
|
}
|
|
var unreadCount int64
|
|
for conversationID, maxSeq := range maxSeqs {
|
|
count := maxSeq - readSeqs[conversationID]
|
|
if count > 0 {
|
|
unreadCount += count
|
|
}
|
|
}
|
|
return &jssdk.GetConversationsResp{
|
|
Conversations: resp,
|
|
UnreadCount: unreadCount,
|
|
}, nil
|
|
}
|