@ -16,22 +16,27 @@ package controller
import (
import (
"context"
"context"
"encoding/json"
"errors"
"errors"
"time"
"time"
"github.com/OpenIMSDK/protocol/constant"
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
"github.com/redis/go-redis/v9"
"github.com/redis/go-redis/v9"
"github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/log"
"github.com/OpenIMSDK/tools/log"
"go.mongodb.org/mongo-driver/mongo"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
"github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
"github.com/openimsdk/open-im-server/v3/pkg/common/kafka"
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
"go.mongodb.org/mongo-driver/mongo"
pbmsg "github.com/OpenIMSDK/protocol/msg"
pbmsg "github.com/OpenIMSDK/protocol/msg"
"github.com/OpenIMSDK/protocol/sdkws"
"github.com/OpenIMSDK/protocol/sdkws"
@ -397,7 +402,7 @@ func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversa
func ( db * commonMsgDatabase ) getMsgBySeqs ( ctx context . Context , userID , conversationID string , seqs [ ] int64 ) ( totalMsgs [ ] * sdkws . MsgData , err error ) {
func ( db * commonMsgDatabase ) getMsgBySeqs ( ctx context . Context , userID , conversationID string , seqs [ ] int64 ) ( totalMsgs [ ] * sdkws . MsgData , err error ) {
for docID , seqs := range db . msg . GetDocIDSeqsMap ( conversationID , seqs ) {
for docID , seqs := range db . msg . GetDocIDSeqsMap ( conversationID , seqs ) {
// log.ZDebug(ctx, "getMsgBySeqs", "docID", docID, "seqs", seqs)
// log.ZDebug(ctx, "getMsgBySeqs", "docID", docID, "seqs", seqs)
msgs , err := db . findMsgInfoBySeq ( ctx , userID , docID , seqs)
msgs , err := db . findMsgInfoBySeq ( ctx , userID , docID , conversationID, seqs)
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}
@ -408,12 +413,94 @@ func (db *commonMsgDatabase) getMsgBySeqs(ctx context.Context, userID, conversat
return totalMsgs , nil
return totalMsgs , nil
}
}
func ( db * commonMsgDatabase ) findMsgInfoBySeq ( ctx context . Context , userID , docID string , seqs [ ] int64 ) ( totalMsgs [ ] * unrelationtb . MsgInfoModel , err error ) {
func ( db * commonMsgDatabase ) handlerDBMsg ( ctx context . Context , cache map [ int64 ] [ ] * unrelationtb . MsgInfoModel , userID , conversationID string , msg * unrelationtb . MsgInfoModel ) {
if msg . IsRead {
msg . Msg . IsRead = true
}
if msg . Msg . ContentType != constant . Quote {
return
}
if msg . Msg . Content == "" {
return
}
type MsgData struct {
SendID string ` protobuf:"bytes,1,opt,name=sendID,proto3" json:"sendID" `
RecvID string ` protobuf:"bytes,2,opt,name=recvID,proto3" json:"recvID" `
GroupID string ` protobuf:"bytes,3,opt,name=groupID,proto3" json:"groupID" `
ClientMsgID string ` protobuf:"bytes,4,opt,name=clientMsgID,proto3" json:"clientMsgID" `
ServerMsgID string ` protobuf:"bytes,5,opt,name=serverMsgID,proto3" json:"serverMsgID" `
SenderPlatformID int32 ` protobuf:"varint,6,opt,name=senderPlatformID,proto3" json:"senderPlatformID" `
SenderNickname string ` protobuf:"bytes,7,opt,name=senderNickname,proto3" json:"senderNickname" `
SenderFaceURL string ` protobuf:"bytes,8,opt,name=senderFaceURL,proto3" json:"senderFaceURL" `
SessionType int32 ` protobuf:"varint,9,opt,name=sessionType,proto3" json:"sessionType" `
MsgFrom int32 ` protobuf:"varint,10,opt,name=msgFrom,proto3" json:"msgFrom" `
ContentType int32 ` protobuf:"varint,11,opt,name=contentType,proto3" json:"contentType" `
Content string ` protobuf:"bytes,12,opt,name=content,proto3" json:"content" `
Seq int64 ` protobuf:"varint,14,opt,name=seq,proto3" json:"seq" `
SendTime int64 ` protobuf:"varint,15,opt,name=sendTime,proto3" json:"sendTime" `
CreateTime int64 ` protobuf:"varint,16,opt,name=createTime,proto3" json:"createTime" `
Status int32 ` protobuf:"varint,17,opt,name=status,proto3" json:"status" `
IsRead bool ` protobuf:"varint,18,opt,name=isRead,proto3" json:"isRead" `
Options map [ string ] bool ` protobuf:"bytes,19,rep,name=options,proto3" json:"options" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3" `
OfflinePushInfo * sdkws . OfflinePushInfo ` protobuf:"bytes,20,opt,name=offlinePushInfo,proto3" json:"offlinePushInfo" `
AtUserIDList [ ] string ` protobuf:"bytes,21,rep,name=atUserIDList,proto3" json:"atUserIDList" `
AttachedInfo string ` protobuf:"bytes,22,opt,name=attachedInfo,proto3" json:"attachedInfo" `
Ex string ` protobuf:"bytes,23,opt,name=ex,proto3" json:"ex" `
}
var quoteMsg struct {
Text string ` json:"text,omitempty" `
QuoteMessage * MsgData ` json:"quoteMessage,omitempty" `
MessageEntityList json . RawMessage ` json:"messageEntityList,omitempty" `
}
if err := json . Unmarshal ( [ ] byte ( msg . Msg . Content ) , & quoteMsg ) ; err != nil {
log . ZError ( ctx , "json.Unmarshal" , err )
return
}
if quoteMsg . QuoteMessage == nil || quoteMsg . QuoteMessage . ContentType == constant . MsgRevokeNotification {
return
}
var msgs [ ] * unrelationtb . MsgInfoModel
if v , ok := cache [ quoteMsg . QuoteMessage . Seq ] ; ok {
msgs = v
} else {
if quoteMsg . QuoteMessage . Seq > 0 {
ms , err := db . msgDocDatabase . GetMsgBySeqIndexIn1Doc ( ctx , userID , db . msg . GetDocID ( conversationID , quoteMsg . QuoteMessage . Seq ) , [ ] int64 { quoteMsg . QuoteMessage . Seq } )
if err != nil {
log . ZError ( ctx , "GetMsgBySeqIndexIn1Doc" , err , "conversationID" , conversationID , "seq" , quoteMsg . QuoteMessage . Seq )
return
}
msgs = ms
cache [ quoteMsg . QuoteMessage . Seq ] = ms
}
}
if len ( msgs ) != 0 && msgs [ 0 ] . Msg . ContentType != constant . MsgRevokeNotification {
return
}
quoteMsg . QuoteMessage . ContentType = constant . MsgRevokeNotification
if len ( msgs ) > 0 {
quoteMsg . QuoteMessage . Content = msgs [ 0 ] . Msg . Content
} else {
quoteMsg . QuoteMessage . Content = "{}"
}
data , err := json . Marshal ( & quoteMsg )
if err != nil {
log . ZError ( ctx , "json.Marshal" , err )
return
}
msg . Msg . Content = string ( data )
if _ , err := db . msgDocDatabase . UpdateMsg ( ctx , db . msg . GetDocID ( conversationID , msg . Msg . Seq ) , db . msg . GetMsgIndex ( msg . Msg . Seq ) , "msg" , msg . Msg ) ; err != nil {
log . ZError ( ctx , "UpdateMsgContent" , err )
}
}
func ( db * commonMsgDatabase ) findMsgInfoBySeq ( ctx context . Context , userID , docID string , conversationID string , seqs [ ] int64 ) ( totalMsgs [ ] * unrelationtb . MsgInfoModel , err error ) {
msgs , err := db . msgDocDatabase . GetMsgBySeqIndexIn1Doc ( ctx , userID , docID , seqs )
msgs , err := db . msgDocDatabase . GetMsgBySeqIndexIn1Doc ( ctx , userID , docID , seqs )
if err != nil {
return nil , err
}
tempCache := make ( map [ int64 ] [ ] * unrelationtb . MsgInfoModel )
for _ , msg := range msgs {
for _ , msg := range msgs {
if msg . IsRead {
db . handlerDBMsg ( ctx , tempCache , userID , conversationID , msg )
msg . Msg . IsRead = true
}
}
}
return msgs , err
return msgs , err
}
}
@ -422,7 +509,7 @@ func (db *commonMsgDatabase) getMsgBySeqsRange(ctx context.Context, userID strin
log . ZDebug ( ctx , "getMsgBySeqsRange" , "conversationID" , conversationID , "allSeqs" , allSeqs , "begin" , begin , "end" , end )
log . ZDebug ( ctx , "getMsgBySeqsRange" , "conversationID" , conversationID , "allSeqs" , allSeqs , "begin" , begin , "end" , end )
for docID , seqs := range db . msg . GetDocIDSeqsMap ( conversationID , allSeqs ) {
for docID , seqs := range db . msg . GetDocIDSeqsMap ( conversationID , allSeqs ) {
log . ZDebug ( ctx , "getMsgBySeqsRange" , "docID" , docID , "seqs" , seqs )
log . ZDebug ( ctx , "getMsgBySeqsRange" , "docID" , docID , "seqs" , seqs )
msgs , err := db . findMsgInfoBySeq ( ctx , userID , docID , seqs)
msgs , err := db . findMsgInfoBySeq ( ctx , userID , docID , conversationID, seqs)
if err != nil {
if err != nil {
return nil , err
return nil , err
}
}